样例未通过,求分析(悬关)
查看原帖
样例未通过,求分析(悬关)
666970
djy123456楼主2024/7/11 13:28

根据第一篇题解写的(相似但不是抄写),变量名较为清晰,结构也与题解类似,求分析

#include <bits/stdc++.h>
using namespace std;
struct point 
{
	double x, y;
};
point turn_point(double x, double y)
{
	point new_point;
	new_point.x = x, new_point.y = y;
	return new_point;
}
point operator + (point a, point b)
{
	point new_point = turn_point(a.x + b.x, a.y + b.y);
}
point operator - (point a, point b)
{
	point new_point = turn_point(a.x - b.x, a.y - b.y);
}
int double_positive(double x)
{
	if(fabs(x) < 1e-10)
		return 0;
	if(x < 0)
		return -1;
	return 1;
}
double dot(point a, point b)
{
	double sum = a.x * b.x + a.y * b.y;
	return sum;
}
double length(point a)
{
	return sqrt(dot(a, a));
}
double cross(point a, point b)
{
	return a.x * b.y - a.y * b.x;
}
double get_slope(point a)
{
	return a.y / a.x;
}
double get_point_distant_to_segment(point a, point b, point c)
{
	point num1 = c - b, num2 = a - b, num3 = a - c;
	if(double_positive(dot(num1, num2)) < 0)
		return length(num2);
	if(double_positive(dot(num1, num3) ) > 0)
		return length(num3);
	return fabs(cross(num1, num2) / length(num1));
}
int last_animate_ant, n, m, end_time;
bool game_over, cake_fly;
struct map
{
	int pheromone;
	bool used;
}a_map[9][9];
int turret_sum, turret_range, turret_damage, target;
struct turret
{
	int will_shoot, x, y;
}t[21];
int born_ant_sum, now_ant_sum;
const double ant_size = 0.5;
struct ant
{
	int now_x, now_y, old, level, health, last_x, last_y;
	double born_health;
	bool dead, get_cake;
}a[200001];
void ant_born()
{
	if (now_ant_sum >= 6 || a_map[0][0].used)
		return;
	born_ant_sum++;
	now_ant_sum++;
	a[born_ant_sum].now_x = 0;
	a[born_ant_sum].now_y = 0;
	a[born_ant_sum].last_x = -1;
	a[born_ant_sum].last_y = -1;
	a[born_ant_sum].old = 0;
	a[born_ant_sum].level = ((born_ant_sum - 1) / 6) + 1;
	a[born_ant_sum].get_cake = 0;
	a[born_ant_sum].dead = 0;
	double health_ture = floor(4 * pow(1.1, a[born_ant_sum].level));
	a[born_ant_sum].health = (int)health_ture;
	a[born_ant_sum].born_health = health_ture;
}
void release_pheromone()
{
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		if(!a[i].get_cake)
			a_map[a[i].now_x][a[i].now_y].pheromone += 2;
		else
			a_map[a[i].now_x][a[i].now_y].pheromone += 5;
	}
	return;
}
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
bool cheak_point_can_be_moved(int x, int y)
{
	if(x < 0)
		return 0;
	if(x>n)
		return 0;
	if(y<0)
		return 0;
	if(y>m)
		return 0;
	if(a_map[x][y].used)
		return 0;
	return 1;
}
void ant_move()
{
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		int max_pheromone = -1, now_direction = -1, direction = -1, nowx, nowy, nowd;
		for(int j = 0; j < 4; j++)
		{
			nowx = a[i].now_x + dx[j];
			nowy = a[i].now_x + dy[j];
			if(!cheak_point_can_be_moved(nowx, nowy)) 
				continue;
			if(nowx == a[i].last_x && nowy == a[i].last_x)
				continue;
			if(max_pheromone < a_map[nowx][nowy].pheromone)
			{
				max_pheromone = a_map[nowx][nowy].pheromone;
				direction = j;
			} 
		}
		if((a[i].old + 1) % 5 == 0 && direction != -1)
		{
			max_pheromone = -1;
			now_direction = -1;
			for(int j = 1; j <= 4; j++)
			{
				nowd = (direction - j) % 4;
				if(nowd < 0)
					nowd += 4;
				nowx = a[i].now_x + dx[nowd];
				nowy = a[i].now_y + dy[nowd];
				if(!cheak_point_can_be_moved(nowx, nowy))
					continue;
				if(nowx == a[i].last_x && nowy == a[i].last_y)
					continue;
				if(max_pheromone < a_map[nowx][nowy].pheromone)
				{
					max_pheromone = a_map[nowx][nowy].pheromone;
					now_direction = nowd;
					break;
				}
			}
		}
		a[i].last_x = a[i].now_x;
		a[i].last_y = a[i].now_y;
		if(max_pheromone == -1)
			continue;
		if((a[i].old + 1) % 5 == 0)
		{
			a[i].now_x += dx[now_direction];
			a[i].now_y += dy[now_direction];
			a_map[a[i].last_x][a[i].last_y].used = 0;
			a_map[a[i].now_x][a[i].now_y].used = 1;
		}
		else
		{
			a[i].now_x += dx[direction];
			a[i].now_y += dy[direction];
			a_map[a[i].last_x][a[i].last_y].used = 0;
			a_map[a[i].now_x][a[i].now_y].used = 1;
		}
	}
	return;
}
void cheak_cake_fly()
{
	if(cake_fly)
		return;
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		if(a[i].now_x == n && a[i].now_y == m)
		{
			target = i;
			cake_fly = 1;
			a[i].get_cake = 1;
			a[i].health += (int)(a[i].born_health / 2);
			a[i].health = min((int)a[i].born_health, a[i].health);
			return;
		}
	}
	return ;
}
double get_distant(int x1,int y1,int x2,int y2)
{
	int sum = ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	
	return sqrt((double)sum);
}
void shoot_at_ant()
{
	for(int i = 1; i <= turret_sum; i++)
	{
		double target_distant = get_distant(t[i].x, t[i].y, a[target].now_x, a[target].now_y);
		if(!cake_fly || target_distant - (double)turret_range > 1e-10)
		{
			double goal_distant, min_distant = 1e9;
			for(int j = last_animate_ant; j <= born_ant_sum; j++)
			{	
				if(a[j].dead)
					continue;
				goal_distant = get_distant(t[i].x, t[i].y, a[j].now_x, a[j].now_y);
				if(goal_distant < min_distant)
				{
					min_distant = goal_distant;
					t[i].will_shoot = j;
				}
			}
			if(min_distant -(double)turret_range > 1e-10)
			{
				t[i].will_shoot = 0;
				continue;
			}
			a[t[i].will_shoot].health -= turret_damage;
		}
		else
		{
			t[i].will_shoot = target;
			point point1 = turn_point(a[t[i].will_shoot].now_x, a[t[i].will_shoot].now_y), point2 = turn_point(t[i].x, t[i].y);
			for(int j = last_animate_ant; j <= born_ant_sum; j++)
			{
				if(a[j].dead)
					continue;
				if(a[j].get_cake)
				{
					a[j].health -= turret_damage;
					continue;
				}
				point point3 = turn_point(a[j].now_x, a[j].now_y);
				double not_goal_distant = get_point_distant_to_segment(point3, point1, point2);
				if(not_goal_distant - ant_size < 1e-10)
				a[j].health -= turret_damage;
				
			}
		}			
	}
}
void clear_bullet_field()
{
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].health >= 0)
			continue;
		if(!a_map[a[i].now_x][a[i].now_y].used)
			continue;
		if(a[i].dead)
			continue;
		now_ant_sum--;
		a_map[a[i].now_x][a[i].now_y].used = 0;
		a[i].now_x = -1;
		a[i].now_y = -1;
		a[i].dead = 1;
		if(a[i].get_cake)
		{
			cake_fly = 0;
			target = 0;
		}
	}
}
void cheak_game_continue()
{
	if(!cake_fly)
		return;
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		if(a[i].now_x || a[i].now_y)
			continue;
		if(!a[i].get_cake)
			continue;
		game_over = 1;
		break;
	}
	return;
}
void ant_grow()
{
	for(int i = last_animate_ant; i <= born_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		a[i].old++;
	}
	return;
}
void pheromone_reduction()
{
	for(int i = 0; i <= n; i++)
		for(int j = 0; j <= m; j++)
		{
			if(a_map[i][j].pheromone)
			a_map[i][j].pheromone--;
		}
	return;
}
void read()
{
	cin >> n >> m >> turret_sum >> turret_damage >> turret_range;
	for(int i = 1; i <= turret_sum;i++)
	{
		cin >> t[i].x >> t[i].y;
		a_map[t[i].x][t[i].y].used = 1;
	}
	cin >> end_time;
	return ;
}
void work()
{
	for(int Time = 1; Time <= end_time; Time++)
	{
		ant_born();
		release_pheromone();
		ant_move();
		cheak_cake_fly();
		shoot_at_ant();
		clear_bullet_field();
		cheak_game_continue();
		if(game_over)
		{
			printf("Game over after %d seconds\n", Time);
			break;
		}
		ant_grow();
		pheromone_reduction();
		for(int i = last_animate_ant; i <= born_ant_sum;i++)
		{
			if(a[i].dead)
				continue;
			else
			{
				last_animate_ant = i;
				break;
			}
		}
	}
	return;
}
void out_put()
{
	if(!game_over)
		printf("The game is going on\n%d\n", now_ant_sum);
	for(int i = last_animate_ant; i <= now_ant_sum; i++)
	{
		if(a[i].dead)
			continue;
		printf("%d %d %d %d %d\n", a[i].old, a[i].level, a[i].health, a[i].now_x, a[i].now_y);
	}
	return;
}
int main()
{
	read();
	work();
	out_put();
	return 0;
}
2024/7/11 13:28
加载中...