In the famous game Angry Birds, players can choose a direction to shoot a blue bird, which can be spilt into three birds to hit those annoying pigs or wood boards. Birds flies in parabola with gravity constant g=9.8m/s2.
This time, Paopao is commanding her birds to break wood boards on the ground following these rules:- Birds are shooted in the starting position (0,Y).
- Birds' initial speed is fixed as V. However, her direction can be arbitrarily determined by Paopao.
- Each Bird can be spilt into three birds in the starting position. Assuming the angle of the orign direction vector is p, the angles after spilting is p-pi/12, p, and p+pi/12(in Radian). Three birds share the same initial speed V. Notice that there is a ceiling with y=Y, that is to say, any birds flying above the starting position will disappear instantly.
- Wood boards are placed on the ground (the y-axis of ground is 0). The thickness of each board can be ignored and each board can be regarded as a simple line with cordinates (x1,0)-(x2,0). Once hit by a bird, the board will disappear. Hitting on the boundary of the board won't break the board and no boards will overlap each other.
Apparently, some boards can be destroyed in the same time with one shoot. Paopao wants to know the least number of shoots she need to destroy all boards.
Input
The problem contains multiple cases.
Each case starts with one integer and two real numbers indicating the number of boards n (1 ≤ n ≤ 16), the initial speed V (0 < V ≤ 1000), and Y (0 < Y ≤ 1000).
The following n lines each contains two real numbers x1, x2 (0 ≤ x1 < x2 ≤ 1000000), describing the cordinates of a board.
Process to the end of file.
Output
For each test case, output the least number of shoots needed to eliminate all boards in a single line. If some board cannot be broken, output -1 instead.
Sample Input
2 1.0 1.0 0 0.0001 0.45 0.45001 3 1.0 1.0 0 0.0001 0.45 0.45001 0.5 0.6
Sample Output
2 -1
稍作预处理然后 bitmask dp
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
//#undef _DEBUG
#ifdef _DEBUG
#define debug_printf(...) printf(__VA_ARGS__)
#else
#define debug_printf(...)
#endif
int n;
double V;
double Y;
const int MAXN = 16;
struct Bridge
{
double x0;
double x1;
};
Bridge bridge[MAXN];
int bridges;
void get()
{
if (scanf ("%d%lf%lf", &n, &V, &Y) == EOF) {
exit(0);
}
for (int i=0; i<n; ++i) {
scanf ("%lf%lf", &bridge[i].x0, &bridge[i].x1);
if (bridge[i].x0 > bridge[i].x1) {
swap (bridge[i].x0, bridge[i].x1);
}
}
bridges = n;
}
struct Shoot
{
double angle;
int hitsBridge;
};
bool isDoubleEqual (double, double);
const double PI = 3.141592653589793;
const double ESP = 1e-7;
const double g = 9.8;
const double SHOOT_ANGLE_OFFSET = ESP / 100;
const int INF = 100000;
bool isDoubleEqual (double x, double y)
{
return fabs (x - y) < ESP;
}
double flyingTime (double virticalVelocity)
{
double v = virticalVelocity;
double ret = (-v + sqrt (v * v + 2.0 * g * Y)) / g;
return ret;
}
double flyingDistance (double angle)
{
double ret = V * cos (angle) * flyingTime (V * sin (angle));
return ret;
}
double angle (double x)
{
double lo = 0.0;
double hi = PI / 2.0;
if (flyingDistance (lo) < x) {
return PI * 2.0;
}
while (fabs (lo - hi) >= ESP / 100) {
double m = (lo + hi) / 2.0;
if (flyingDistance (m) < x) {
hi = m;
} else {
lo = m;
}
}
return lo;
}
Shoot shoot[MAXN * 6];
int shoots;
double dAngle[3] = {-PI / 12.0, 0.0, PI / 12.0};
void print_shoots (bool printHitsBridge)
{
debug_printf ("\n%d shoots:\n", shoots);
for (int s=0; s<shoots; ++s) {
debug_printf ("ang: %.6lf", shoot[s].angle);
if (printHitsBridge) {
for (int b=0; b<bridges; ++b) {
if ((1 << b) & shoot[s].hitsBridge) {
debug_printf (" %d", b);
}
}
}
debug_printf ("\n");
}
}
void makeShoots()
{
debug_printf ("\n%d bridges:\n", bridges);
for (int i=0; i<bridges; ++i) {
debug_printf ("(%.6lf, %.6lf)\n", bridge[i].x0, bridge[i].x1);
}
shoots = 0;
for (int i=0; i<bridges; ++i) {
for (int a=0; a<3; ++a) {
shoot[shoots++].angle = angle (bridge[i].x0) + dAngle[a] - SHOOT_ANGLE_OFFSET;
}
for (int a=0; a<3; ++a) {
shoot[shoots++].angle = angle (bridge[i].x1) + dAngle[a] + SHOOT_ANGLE_OFFSET;
}
}
for (int i=0; i<shoots; ++i) {
shoot[i].hitsBridge = 0;
}
for (int s=0; s<shoots; ++s) {
for (int a=0; a<3; ++a) {
debug_printf ("s = %d, a = %d\n", s, a);
double ang = shoot[s].angle + dAngle[a];
if (ang < 0 || PI / 2.0 < ang) {
continue;
}
double fd = flyingDistance (ang);
debug_printf ("flyingDistance (%.6lf) == %.6lf\n", ang, fd);
for (int b=0; b<bridges; ++b) {
if (bridge[b].x0 <= fd && fd <= bridge[b].x1) {
shoot[s].hitsBridge |= (1 << b);
}
} // for all bridges
} // for 3 angles
} // for all shoots
// remove unsignificant shoots
for (int s=0; s<shoots; ++s) {
if (shoot[s].hitsBridge == 0) {
debug_printf ("shoot[%d]: angle = %.6lf, hits no bridge\n", s, shoot[s].angle);
swap (shoot[s], shoot[shoots - 1]);
--shoots;
--s;
}
}
print_shoots (true);
}
bool bridgeBroken[MAXN];
int dp[1 << MAXN];
int minShoots (int bridgeMask)
{
if (dp[bridgeMask] != -1) {
return dp[bridgeMask];
}
if (bridgeMask == 0) {
return dp[bridgeMask] = 0;
}
dp[bridgeMask] = INF;
for (int s=0; s<shoots; ++s) {
int nextBridgeMask = bridgeMask & ~shoot[s].hitsBridge;
if (nextBridgeMask != bridgeMask) {
int nextMinShoots = minShoots (nextBridgeMask);
if (nextMinShoots + 1 < dp[bridgeMask]) {
dp[bridgeMask] = nextMinShoots + 1;
}
}
}
return dp[bridgeMask];
}
int main (int argc, char **argv)
{
while (true) {
get();
makeShoots();
memset (dp, -1, sizeof (dp));
int ans = minShoots ((1 << n) - 1);
if (ans >= INF) {
printf ("-1\n");
} else {
printf ("%d\n", ans);
}
}
return 0;
}
本文深入探讨了游戏开发领域的多种技术,包括Unity、Cocos2d-X等游戏引擎,以及人工智能和音视频处理技术的应用,如AR特效、语音识别、图像处理等。同时,文章还涉及了大数据开发、云计算、DevOps等现代技术栈,旨在为开发者提供全面的技术视角。
&spm=1001.2101.3001.5002&articleId=7329156&d=1&t=3&u=4c522889817342c4af715932a32f4686)
2745

被折叠的 条评论
为什么被折叠?



