根据第一篇题解写的(相似但不是抄写),变量名较为清晰,结构也与题解类似,求分析
#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;
}