蒟蒻の问题
  • 板块P5506 封锁
  • 楼主imfkwk
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/4/11 18:12
  • 上次更新2023/11/5 00:40:48
查看原帖
蒟蒻の问题
389540
imfkwk楼主2021/4/11 18:12

前言:我没过,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;
}
2021/4/11 18:12
加载中...