前言:我没过,58pts,讨论区没有我的问题
枚举路径肯定耗时间啊
虽然之前写飞行棋是这样写的
那么更优秀的做法就是枚举每一个飞机然后观察坐标,这样也可以避免距离的讨论了。
对于每一次攻击,枚举活着的飞机。把xyz相减,得到一组坐标差。
如果坐标差是0(在一条直线上),但是攻击方向却偏离了这条直线或者和这条直线相反,那么肯定打不到。所以,只有当坐标差和方向同正或者同负或者同0的时候才可能击中。
int x = p[i].x;
int y = p[i].y;
int z = p[i].z;
if (x == p[num].x && y == p[num].y && z == p[num].z)
continue;
int cx = x - p[num].x;
int cy = y - p[num].y;
int cz = z - p[num].z;
if (cx != 0 && !fx[p[num].f] || cx < 0 && fx[p[num].f] > 0 || cx > 0 && fx[p[num].f] < 0)
continue;
if (cy != 0 && !fy[p[num].f] || cy < 0 && fy[p[num].f] > 0 || cy > 0 && fy[p[num].f] < 0)
continue;
if (cz != 0 && !fz[p[num].h] || cz < 0 && fz[p[num].h] > 0 || cz > 0 && fz[p[num].h] < 0)
continue;
这样方向肯定是正确的,然后再看距离。
int len1 = 0, len2 = 0, len3 = 0;
if (cx)
len1 = cx / fx[p[num].f];
if (cy)
len2 = cy / fy[p[num].f];
if (cz)
len3 = cz / fz[p[num].h];
if (!len1)
if (len2) len1 = len2;
else len1 = len3;
if (!len2)
if (len1) len2 = len1;
else len2 = len3;
if (!len3)
if (len1) len3 = len1;
else len3 = len2;
if (!(len1 == len2 && len2 == len3))
continue;
有的位移是0,那么不比较它,只要不为零的位移全部相等,就证明再正前方了。
然后锅了。求助。
subtask5的前两个点和subtask6。
源码
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x)
{
x = 0; bool c = 1;
char ch = getchar();
while (ch < 48 || ch > 57)
{
c = !(ch == 45);
ch = getchar();
}
while (ch >= 48 && ch <= 57)
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
x = c ? x : -x;
}
int n, t;
int fx[] = {1, 1, 0, -1, -1, -1, 0, 1};
int fy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int fz[] = {-1, -1, 0, 1, 1};
struct plane
{
int x, y, z;
int h;
int f;
int atk;
int def;
int mat;
int mdf;
int hp;
int fix;
char move[101];
};
struct node
{
int len;
int num;
};
plane p[101];
bool cmp(node a, node b) {return a.len == b.len ? a.num < b.num : a.len < b.len;}
inline void move(int num, int time)
{
char m = p[num].move[time];
if (m == 'N')
return;
if (m == 'U' || m == 'D')
{
if (m == 'U')
p[num].h = min(4, p[num].h + 1);
else if (m == 'D')
p[num].h = max(0, p[num].h - 1);
return;
}
else if (m == 'L' || m == 'R')
{
if (m == 'R')
p[num].f = (p[num].f + 7) % 8;
else if (m == 'L')
p[num].f = (p[num].f + 1) % 8;
return;
}
else if (m == 'F')
{
p[num].hp += p[num].fix;
return;
}
else if (m == 'A')
{
node ch[101];
int cnt = 0;
for (register int i = 1; i <= n; ++i)
{
if (i == num)
continue;
if (!p[i].hp)
continue;
int x = p[i].x;
int y = p[i].y;
int z = p[i].z;
if (x == p[num].x && y == p[num].y && z == p[num].z)
continue;
int cx = x - p[num].x;
int cy = y - p[num].y;
int cz = z - p[num].z;
if (cx != 0 && !fx[p[num].f] || cx < 0 && fx[p[num].f] > 0 || cx > 0 && fx[p[num].f] < 0)
continue;
if (cy != 0 && !fy[p[num].f] || cy < 0 && fy[p[num].f] > 0 || cy > 0 && fy[p[num].f] < 0)
continue;
if (cz != 0 && !fz[p[num].h] || cz < 0 && fz[p[num].h] > 0 || cz > 0 && fz[p[num].h] < 0)
continue;
int len1 = 0, len2 = 0, len3 = 0;
if (cx)
len1 = cx / fx[p[num].f];
if (cy)
len2 = cy / fy[p[num].f];
if (cz)
len3 = cz / fz[p[num].h];
if (!len1)
if (len2) len1 = len2;
else len1 = len3;
if (!len2)
if (len1) len2 = len1;
else len2 = len3;
if (!len3)
if (len1) len3 = len1;
else len3 = len2;
if (!(len1 == len2 && len2 == len3))
continue;
ch[++cnt] = (node){len1, i};
}
sort(ch + 1, ch + cnt + 1, cmp);
int t = ch[1].num;
p[t].hp = max(0, p[t].hp - max(0, p[num].atk - p[t].def));
}
else if (m == 'M')
{
for (register int i = 1; i <= n; ++i)
{
if (i == num)
continue;
if (!p[i].hp)
continue;
int x = p[i].x;
int y = p[i].y;
int z = p[i].z;
if (x == p[num].x && y == p[num].y && z == p[num].z)
continue;
int cx = x - p[num].x;
int cy = y - p[num].y;
int cz = z - p[num].z;
if (cx != 0 && !fx[p[num].f] || cx < 0 && fx[p[num].f] > 0 || cx > 0 && fx[p[num].f] < 0)
continue;
if (cy != 0 && !fy[p[num].f] || cy < 0 && fy[p[num].f] > 0 || cy > 0 && fy[p[num].f] < 0)
continue;
if (cz != 0 && !fz[p[num].h] || cz < 0 && fz[p[num].h] > 0 || cz > 0 && fz[p[num].h] < 0)
continue;
int len1 = 0, len2 = 0, len3 = 0;
if (cx)
len1 = cx / fx[p[num].f];
if (cy)
len2 = cy / fy[p[num].f];
if (cz)
len3 = cz / fz[p[num].h];
if (!len1)
if (len2) len1 = len2;
else len1 = len3;
if (!len2)
if (len1) len2 = len1;
else len2 = len3;
if (!len3)
if (len1) len3 = len1;
else len3 = len2;
if (!(len1 == len2 && len2 == len3))
continue;
p[i].hp = max(0, p[i].hp - max(0, p[num].mat - p[i].mdf));
}
}
}
signed main(void)
{
read(n); read(t);
for (register int i = 1; i <= n; ++i)
{
read(p[i].x); read(p[i].y); read(p[i].z);
read(p[i].h); read(p[i].f);
read(p[i].atk);
read(p[i].def);
read(p[i].mat);
read(p[i].mdf);
read(p[i].hp);
read(p[i].fix);
for (register int j = 1; j <= t; ++j)
p[i].move[j] = getchar();
}
for (register int i = 1; i <= t; ++i)
{
for (register int j = 1; j <= n; ++j)
{
if (p[j].hp)
{
p[j].z += fz[p[j].h];
if (p[j].h != 0 && p[j].h != 4)
{
p[j].x += fx[p[j].f];
p[j].y += fy[p[j].f];
}
}
}
for (register int j = 1; j <= n; ++j)
if (p[j].hp)
move(j, i);
}
for (register int i = 1; i <= n; ++i)
printf("%d %d %d %d\n", p[i].x, p[i].y, p[i].z, p[i].hp);
return 0;
}