[CF750D] New Year and Fireworks(暴力,规律,dfs)
题目链接:http://codeforces.com/contest/750/problem/D
题意:烟花看做n层,第i层的格子可以朝45°方向的格子扩展ti次,问有多少格子可以被经过。
vis(x,y,i,dir,st)表示(x,y)点在第i层,由dir方向,走了st步过来。写好方向的元组,每次转45° 直接dfs就行。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 31; 5 const int maxm = 301; 6 const int dir[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}}; 7 // vis(x,y,i,dir,st) 8 bool vis[maxm][maxm][maxn][8][6], G[maxm][maxm]; 9 int n, t[maxn], ret; 10 11 void dfs(int x, int y, int i, int d, int st) { 12 if(vis[x][y][i][d][st]) return; 13 if(i == n) return; 14 vis[x][y][i][d][st] = 1; 15 if(!G[x][y]) ret++; 16 G[x][y] = 1; 17 if(st < t[i]) dfs(x+dir[d][0],y+dir[d][1],i,d,st+1); 18 else { 19 dfs(x,y,i+1,(d-1+8)%8,0); 20 dfs(x,y,i+1,(d+1)%8,0); 21 } 22 } 23 24 signed main() { 25 // freopen("in", "r", stdin); 26 while(~scanf("%d", &n)) { 27 memset(vis, 0, sizeof(vis)); 28 memset(G, 0, sizeof(G)); 29 ret = 0; 30 for(int i = 0; i < n; i++) { 31 scanf("%d", &t[i]); 32 } 33 dfs(150,150,0,0,1); 34 printf("%d\n", ret); 35 } 36 return 0; 37 }