http://codeforces.com/contest/750/problem/D
题意:烟花会绽放n次,每次会向前推进t[i]格,每次绽放会向左右45°绽放,问有烟花的格子数。
思路:n = 30, t = 5,所以最多推进150格。范围很小,开一个300*300的数组,初始位置在(150, 150),直接BFS。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <queue> 8 #include <vector> 9 #include <map> 10 #include <set> 11 using namespace std; 12 #define INF 0x3f3f3f3f 13 #define N 310 14 typedef long long LL; 15 struct P { 16 int x, y, step, dir; 17 P () {} 18 P (int x, int y, int step, int dir) : x(x), y(y), step(step), dir(dir) {} 19 }; 20 int ans, t[N]; 21 bool mp[N][N]; 22 bool vis[N][N][32][10]; 23 int d[][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; 24 // 八个方向顺时针 25 void BFS(int n) { 26 queue<P> que; 27 while(!que.empty()) que.pop(); 28 memset(vis, 0, sizeof(vis)); 29 memset(mp, 0, sizeof(mp)); 30 ans = 0; 31 vis[150][150][1][0] = 1; // 初始位置 32 que.push(P(150, 150, 1, 0)); 33 while(!que.empty()) { 34 P f = que.front(); que.pop(); 35 int nx = f.x, ny = f.y, step = f.step, dd = f.dir; 36 for(int i = 1; i <= t[step]; i++) { // 处理这一层的绽放情况 37 nx += d[dd][0]; 38 ny += d[dd][1]; 39 mp[nx][ny] = 1; 40 } 41 if(step < n) { // 向左右绽放 42 int dl = ((dd - 1) + 8) % 8, dr = (dd + 1) % 8; 43 if(!vis[nx][ny][step+1][dl]) { 44 vis[nx][ny][step+1][dl] = 1; 45 que.push(P(nx, ny, step + 1, dl)); 46 } 47 if(!vis[nx][ny][step+1][dr]) { 48 vis[nx][ny][step+1][dr] = 1; 49 que.push(P(nx, ny, step + 1, dr)); 50 } 51 } 52 } 53 for(int i = 0; i <= 300; i++) 54 for(int j = 0; j <= 300; j++) 55 if(mp[i][j]) ans++; 56 } 57 58 int main() { 59 int n; 60 cin >> n; 61 for(int i = 1; i <= n; i++) cin >> t[i]; 62 BFS(n); 63 printf("%d ", ans); 64 return 0; 65 }