还是比较好写的......其中最毒瘤的版块居然TM是计算几何......
巨型模拟。
主要难点是判断线段与圆是否相交,查错困难。
写出来没花太长时间,调试倒是一个状态一个状态的输出,和std对比,烦死了。
1 // kill ant 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 6 #define wwx_AK_IOI huyufeifei::main() 7 8 namespace huyufeifei { 9 10 const int N = 200010, INF = 0x3f3f3f3f; 11 const int dx[] = {0, 1, 0, -1}; 12 const int dy[] = {1, 0, -1, 0}; 13 14 struct ANT { 15 int bir, hp, max_hp, x, y, last_x, last_y, level; 16 bool cake; 17 }a[10]; int top; 18 19 struct TOWER { 20 int x, y; 21 }b[50]; 22 23 int tot, G[30][30], cake = -1, d, r, n, m, s, time, vis[30][30]; 24 25 inline void birth_ant() { 26 if(top < 6 && !vis[0][0]) { 27 top++; 28 tot++; 29 a[top].bir = time; 30 a[top].level = (tot - 1) / 6 + 1; 31 a[top].max_hp = int(4 * pow(1.1, a[top].level)); 32 a[top].hp = a[top].max_hp; 33 a[top].cake = 0; 34 a[top].x = 0; 35 a[top].y = 0; 36 a[top].last_x = -1; 37 a[top].last_y = -1; 38 vis[0][0] = top; 39 } 40 return; 41 } 42 43 inline void make_information() { 44 for(int i = 1; i <= top; i++) { 45 G[a[i].x][a[i].y] += (a[i].cake ? 5 : 2); 46 } 47 return; 48 } 49 50 inline bool valid(int i, int j) { 51 int x = a[i].x + dx[j]; 52 int y = a[i].y + dy[j]; 53 if(x == a[i].last_x && y == a[i].last_y) { 54 return 0; 55 } 56 if(x < 0 || y < 0 || x > n || y > m) { 57 return 0; 58 } 59 if(vis[x][y] || G[x][y] == -1) { 60 return 0; 61 } 62 return 1; 63 } 64 65 inline void move() { 66 for(int i = 1; i <= top; i++) { 67 int direct = -1, large = -1; 68 for(int j = 0; j < 4; j++) { 69 if(valid(i, j)) { 70 if(G[a[i].x + dx[j]][a[i].y + dy[j]] > large) { 71 large = G[a[i].x + dx[j]][a[i].y + dy[j]]; 72 direct = j; 73 } 74 } 75 } 76 // 77 if((time - a[i].bir + 1) % 5 == 0 && direct != -1) { 78 do { 79 direct--; 80 if(direct < 0) { 81 direct = 3; 82 } 83 } while(!valid(i, direct)); 84 } 85 // go to direct 86 a[i].last_x = a[i].x; 87 a[i].last_y = a[i].y; 88 if(direct != -1) { 89 a[i].x += dx[direct]; 90 a[i].y += dy[direct]; 91 vis[a[i].x][a[i].y] = i; 92 vis[a[i].last_x][a[i].last_y] = 0; 93 } 94 // over 95 } 96 return; 97 } 98 99 inline void check_cake() { 100 int i = vis[n][m]; 101 if(i) { 102 cake = i; 103 a[i].cake = 1; 104 a[i].hp += (a[i].max_hp >> 1); 105 a[i].hp = std::min(a[i].hp, a[i].max_hp); 106 } 107 return; 108 } 109 110 inline int get_aim(int x, int y) { 111 if(cake != -1 && (x - a[cake].x) * (x - a[cake].x) + (y - a[cake].y) * (y - a[cake].y) <= r * r) { 112 return cake; 113 } 114 int small = INF, aim = -1; 115 for(int i = 1; i <= top; i++) { 116 if(small > (x - a[i].x) * (x - a[i].x) + (y - a[i].y) * (y - a[i].y)) { 117 small = (x - a[i].x) * (x - a[i].x) + (y - a[i].y) * (y - a[i].y); 118 aim = i; 119 } 120 } 121 if(small <= r * r) { 122 return aim; 123 } 124 return 0; 125 } 126 127 struct Point { 128 double x, y; 129 Point(double _x = 0, double _y = 0) { 130 x = _x; 131 y = _y; 132 } 133 }; 134 135 inline bool influence(int pa, int pb, int pc) { 136 int A = b[pa].x; 137 int B = b[pa].y; 138 int C = a[pb].x; 139 int D = a[pb].y; 140 int E = a[pc].x; 141 int F = a[pc].y; 142 143 if(A == C) { 144 int d2 = (E - C) * (E - C); 145 if(F < std::min(B, D) || F > std::max(B, D)) { 146 d2 = std::min((E - C) * (E - C) + (F - D) * (F - D), 147 (E - A) * (E - A) + (F - B) * (F - B)); 148 } 149 //printf("%d < %d * %d ", d2, r, r); 150 return (double)d2 <= 0.25; 151 } 152 if(B == D) { 153 int d2 = (F - D) * (F - D); 154 if(E < std::min(A, C) || E > std::max(A, C)) { 155 d2 = std::min((E - C) * (E - C) + (F - D) * (F - D), 156 (E - A) * (E - A) + (F - B) * (F - B)); 157 } 158 //printf("%d < %d * %d ", d2, r, r); 159 return (double)d2 <= 0.25; 160 } 161 162 double A1 = (double)(B - D) / (A - C); 163 double C1 = (double)(B) - A1 * A; 164 double B1 = -1.0; 165 166 double A2 = -1.0 / A1; 167 double B2 = -1.0; 168 double C2 = 1.0 * F - A2 * E; 169 Point p((B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1), (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1)); 170 171 double d2 = (p.x - E) * (p.x - E) + (p.y - F) * (p.y - F); 172 if(p.x < std::min(A, C) || p.x > std::max(A, C)) { 173 d2 = std::min((E - C) * (E - C) + (F - D) * (F - D), 174 (E - A) * (E - A) + (F - B) * (F - B)); 175 } 176 //printf("%d ", d2 < r * r); <- error 177 return d2 <= 0.25; 178 } 179 180 inline bool update(int i) { 181 if(i > top) { 182 return 0; 183 } 184 if(a[i].hp < 0) { 185 if(a[i].cake) { 186 cake = -1; 187 } 188 vis[a[i].x][a[i].y] = 0; // error : space 189 for(int j = i; j < top; j++) { 190 a[j] = a[j + 1]; 191 if(a[j].cake) { 192 cake = j; 193 } 194 vis[a[j].x][a[j].y] = j; // error : space 195 } 196 top--; 197 return 1; 198 } 199 return 0; 200 } 201 202 inline void attack() { 203 for(int i = 1; i <= s; i++) { 204 int j = get_aim(b[i].x, b[i].y); 205 if(!j) { 206 continue; 207 } 208 a[j].hp -= d; 209 for(int k = 1; k <= top; k++) { 210 if(k != j && influence(i, j, k)) { 211 a[k].hp -= d; 212 } 213 } 214 } 215 for(int i = 1; i <= top; i++) { 216 while(update(i)) { // error : space 217 update(i); 218 } 219 } 220 return; 221 } 222 223 inline bool check_ed() { 224 return cake != -1 && !a[cake].x && !a[cake].y; 225 } 226 227 inline void del_information() { 228 for(int i = 0; i <= n; i++) { 229 for(int j = 0; j <= m; j++) { 230 if(G[i][j] > 0) { 231 G[i][j]--; 232 } 233 } 234 } 235 return; 236 } 237 238 inline void out() { 239 printf("%d ", top); 240 for(int i = 1; i <= top; i++) { 241 printf("%d %d %d %d %d ", time - a[i].bir, a[i].level, a[i].hp, a[i].x, a[i].y); 242 } 243 /*puts(""); 244 for(int i = 0; i <= n; i++) { 245 for(int j = 0; j <= m; j++) { 246 if(G[i][j] >= 0) { 247 printf("%3d", vis[i][j]); 248 } 249 else { 250 printf(" -1"); 251 } 252 } 253 puts(""); 254 }*/ 255 return; 256 } 257 258 inline void main() { 259 //freopen("in.in", "r", stdin); 260 //freopen("my.out", "w", stdout); 261 scanf("%d%d", &n, &m); 262 scanf("%d%d%d", &s, &d, &r); 263 for(int i = 1; i <= s; i++) { 264 scanf("%d%d", &b[i].x, &b[i].y); 265 G[b[i].x][b[i].y] = -1; 266 } 267 int T; 268 scanf("%d", &T); 269 270 for(time = 1; time <= T; time++) { 271 birth_ant(); 272 make_information(); 273 move(); 274 if(cake == -1) { 275 check_cake(); 276 } 277 attack(); 278 int t = check_ed(); 279 if(t) { 280 printf("Game over after %d seconds ", time); 281 out(); 282 return; 283 } 284 del_information(); 285 //out(); 286 } 287 printf("The game is going on "); 288 out(); 289 return; 290 } 291 292 } 293 294 int main() { 295 wwx_AK_IOI; 296 return 0; 297 }