(´;ω;`)
有以下几点要注意:
1,蚂蚁不是质点。
2,蚂蚁的直径是1,不是半径是1。
3,给蚂蚁按age排序的时候,不要忘了target也得跟着变。
4,过早优化就是死,直接维护信息素的值就好了,每回合都O(nm)减一次,不要想着用时间戳。
5,蚂蚁上次移动位置的更新要注意放对位置,因为下面可能还有check相邻位置能不能走。
6,注意target的更新位置。
7,炮塔是一起攻击的,所以就算某只蚂蚁的血被打成了负,还是要被攻击。
8,判断激光是否能扫到其他蚂蚁的时候,注意double运算的精度,因为开了-O2,所以很可能出问题。返回类型为double的函数不要开inline,不要放在struct内。
⑨,大程序就不要缩行了。
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 10, maxs = 25, maxa = 10, inf = 0x3f3f3f3f;
const double eps = 1e-5;
const int maxant = 6;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
inline int sqr(int x) {
return x * x;
}
inline int dis(int x1, int y1, int x2, int y2) {
return sqr(x1 - x2) + sqr(y1 - y2);
}
double getcos(int x1, int y1, int x2, int y2, int x3, int y3) {
int a1 = x1 - x2, b1 = y1 - y2, a2 = x3 - x2, b2 = y3 - y2;
return (a1 * a2 + b1 * b2) / (double)(sqrt(dis(x1, y1, x2, y2)) * sqrt(dis(x3, y3, x2, y2)));
}
struct _game {
struct _turret {
int x, y;
_turret() {
x = y = 0;
}
};
struct _ant {
int x, y, oldx, oldy;
int age, level, inithealth, health;
bool dead;
_ant() {
x = y = oldx = oldy = 0;
age = level = inithealth = health = 0;
dead = 1;
}
bool operator < (const _ant &a) const {
if(dead) return 0;
if(a.dead) return 1;
return age > a.age;
}
};
int n, m, g[maxn][maxn], target;
bool blocked[maxn][maxn], over;
int turretcnt, damage, radius;
_turret turret[maxs];
int antcnt, antsum;
_ant ant[maxa];
void init() {
n = m = over = target = turretcnt = damage = radius = antcnt = antsum = 0;
for(int i = 0; i < maxn; i++) for(int j = 0; j < maxn; j++) g[i][j] = blocked[i][j] = 0;
scanf("%d%d", &n, &m);
scanf("%d%d%d", &turretcnt, &damage, &radius);
for(int i = 1; i <= turretcnt; i++) {
int x, y; scanf("%d%d", &x, &y);
turret[i].x = x; turret[i].y = y;
blocked[x][y] = 1;
}
}
void antsort() {
for(int i = 1; i <= maxant; i++) for(int j = i + 1; j <= maxant; j++)
if(ant[j] < ant[i]) {
swap(ant[j], ant[i]);
if(target == i) target = j;
else if(target == j) target = i;
}
}
void spawnant() {
if(antcnt < maxant && !blocked[0][0]) {
antcnt++; antsum++;
for(int i = 1; i <= maxant; i++)
if(ant[i].dead) {
ant[i].x = ant[i].y = ant[i].oldx = ant[i].oldy = 0;
ant[i].age = 1;
ant[i].level = (antsum - 1) / 6 + 1;
ant[i].inithealth = int(4 * pow(1.1, ant[i].level));
ant[i].health = ant[i].inithealth;
ant[i].dead = 0;
blocked[0][0] = 1;
break;
}
}
antsort();
}
bool check(int x, int y, int id) {
if(x < 0 || x > n || y < 0 || y > m) return 0;
if(blocked[x][y]) return 0;
if(x == ant[id].oldx && y == ant[id].oldy) return 0;
return 1;
}
void move(int id) {
int dir, maxinfo = -1, x = ant[id].x, y = ant[id].y;
for(int i = 0; i < 4; i++) {
int xx = x + dx[i], yy = y + dy[i];
if(!check(xx, yy, id)) continue;
maxinfo = max(maxinfo, g[xx][yy]);
}
if(maxinfo == -1) {
ant[id].oldx = ant[id].x;
ant[id].oldy = ant[id].y;
return;
}
for(int i = 0; i < 4; i++) {
int xx = x + dx[i], yy = y + dy[i];
if(!check(xx, yy, id)) continue;
if(g[xx][yy] == maxinfo) {
dir = i;
break;
}
}
if(ant[id].age % 5 == 0)
for(int i = (dir - 1 + 4) % 4; i != dir; i = (i - 1 + 4) % 4) {
int xx = x + dx[i], yy = y + dy[i];
if(!check(xx, yy, id)) continue;
dir = i;
break;
}
ant[id].oldx = ant[id].x;
ant[id].oldy = ant[id].y;
blocked[ant[id].x][ant[id].y] = 0;
ant[id].x += dx[dir];
ant[id].y += dy[dir];
blocked[ant[id].x][ant[id].y] = 1;
return;
}
void makeinfo() {
for(int i = 1; i <= antcnt; i++)
g[ant[i].x][ant[i].y] += 2 + (target == i) * 3;
}
void moveant() {
for(int i = 1; i <= antcnt; i++)
move(i);
}
void checkcake() {
if(target) return;
for(int i = 1; i <= antcnt; i++)
if(ant[i].x == n && ant[i].y == m) {
target = i;
ant[i].health = min(ant[i].inithealth, ant[i].health + ant[i].inithealth / 2);
}
}
int pdisp(int turid, int antid) {
return dis(turret[turid].x, turret[turid].y, ant[antid].x, ant[antid].y);
}
bool reached(int turid, int antid, int inno) {
double cos1 = getcos(ant[inno].x, ant[inno].y, turret[turid].x, turret[turid].y, ant[antid].x, ant[antid].y);
double cos2 = getcos(ant[inno].x, ant[inno].y, ant[antid].x, ant[antid].y, turret[turid].x, turret[turid].y);
if(cos1 < eps || cos2 < eps) return 0;
double d = sqrt(dis(ant[inno].x, ant[inno].y, turret[turid].x, turret[turid].y)) * sqrt(1.0 - cos1 * cos1);
return d - 0.5 < eps;
}
void attack() {
for(int i = 1; i <= turretcnt; i++) {
if(target && pdisp(i, target) <= sqr(radius)) {
for(int j = 1; j <= antcnt; j++) if(reached(i, target, j))
ant[j].health -= damage;
} else {
int id = 0, range = inf;
for(int j = 1; j <= antcnt; j++) if((pdisp(i, j) < range || (pdisp(i, j) == range && ant[id].age < ant[j].age))) {
range = pdisp(i, j);
id = j;
}
if(range > sqr(radius)) continue;
ant[id].health -= damage;
}
}
}
void checkdead() {
for(int i = 1; i <= maxant; i++)
if(!ant[i].dead && blocked[ant[i].x][ant[i].y] && ant[i].health < 0) {
ant[i].dead = 1;
antcnt--;
blocked[ant[i].x][ant[i].y] = 0;
}
if(target && ant[target].dead) target = 0;
}
void checkover() {
if(!ant[target].dead && ant[target].x == 0 && ant[target].y == 0)
over = 1;
}
void checkant() {
for(int i = 1; i <= maxant; i++) if(!ant[i].dead) ant[i].age++;
}
void checkmap() {
for(int i = 0; i <= n; i++) for(int j = 0; j <= m; j++) if(g[i][j])
g[i][j]--;
}
bool update() {
spawnant();
makeinfo();
moveant();
checkcake();
attack();
checkdead();
checkover();
if(over) return 0;
checkant();
checkmap();
return 1;
}
void print() {
printf("%d\n", antcnt);
antsort();
for(int i = 1; i <= antcnt; i++)
printf("%d %d %d %d %d\n", ant[i].age - 1, ant[i].level, ant[i].health, ant[i].x, ant[i].y);
}
} antbuster;
int main() {
antbuster.init();
int x, T; scanf("%d", &T);
for(x = 1; x <= T; x++)
if(!antbuster.update()) break;
if(x == T + 1) printf("The game is going on\n");
else printf("Game over after %d seconds\n", x);
antbuster.print();
return 0;
}
几组数据:
2.in
4 4
4 10 5
1 1
2 2
1 2
2 1
1000
2.out
Game over after 831 seconds
6
110 49 86 2 3
88 49 26 0 1
77 49 286 3 1
58 50 29 0 0
22 50 419 4 3
10 50 469 3 2
6.in
6 4
1 10000 10
2 2
256
6.out
The game is going on
0
4 7
0 0 0
60200
7.out
Game over after 60200 seconds
6
60199 1 4 0 0
60198 1 4 2 6
60197 1 4 4 7
60196 1 4 2 1
60195 1 4 3 5
60194 1 4 4 5
一组大数据
8.in
2 5
6 1 3
0 1
1 1
1 3
1 4
2 3
2 4
200000
8.out
The game is going on
6
15311 86 13525 1 5
12518 86 10203 0 5
9447 87 12495 0 4
6371 87 13461 0 3
3295 87 14586 0 2
219 87 15873 1 2