Codefroces 750D:New Year and Fireworks(BFS)

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\n", ans);
64     return 0;
65 }

 

转载于:https://www.cnblogs.com/fightfordream/p/6239562.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值