(´;ω;`)
有以下几点要注意:
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 10002.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 4 1 10000 10 2 2 2566.out
The game is going on 0
4 7 0 0 0 602007.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 2000008.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