牛客寒假算法基础训练营6 J 迷宫 (双端队列+BFS)

这一题在左右移动距离上给出了限制,总结下来,就是在上下移动不限,左右移动有界的情况下求出能走到的最多的格子。

我是用了BFS+双端队列的方法过了这题,标准题解没太理解。

接下来直接贴代码,具体说明在代码上会标注

1 /*========================================*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<string>
  5 #include<cstring>
  6 #include<map>
  7 #include<set>
  8 #include<stack>
  9 #include<queue>
 10 #include<deque>
 11 //priority_queue
 12 #include<list>
 13 #include<cstdio>
 14 #include<cmath>
 15 #include<cstring>
 16 #include<cctype>
 17 #include<cstdlib>
 18 #include<ctime>
 19 #include<complex>//.real.imag
 20 #define rep(i,a) for(int i=0;i<a;++i)
 21 #define repd(i,a) for(int i=1;i<=a;++i)
 22 #define pii pair<int,int>
 23 #define pll pair<long long,long long>
 24 #define pdd pair<double,double>
 25 #define rbf(a) for(auto elem:a)
 26 #define MAXI INT_MAX
 27 #define MINI INT_MIN
 28 typedef long long ll;
 29 const int INF = 0x3f3f3f3f;
 30 bool isprime(ll num)
 31 {
 32     if(num == 1)
 33         return 0;
 34     if(num == 2 || num == 3)
 35         return 1;
 36     if(num % 6 != 1 && num % 6 != 5)
 37         return 0;
 38     ll t = sqrt(num);
 39     for(ll i = 5; i <= t; i += 6)
 40     {
 41         if(num % i == 0 || num % (i + 2) == 0)
 42             return 0;
 43     }
 44     return 1;
 45 }
 46 using namespace std;
 47 /*========================================*/
 48 //start your show!
 49 struct node
 50 {
 51     int x, y, l, r;
 52 };//定义每个点的结构体
 53 int d[8] = {0, 0, -1, 1, -1, 1, 0, 0}; //左右上下,在调用时只需要用d[i]+d[i+4]来表明移动状态
 54 int vis[1010][1010];//因为最后要求的是到了多少点,所以我用一个二维数组来存,到的点就为1
 55 char mp[1010][1010];//字符地图
 56 int n, m, r, c, x, y;//n,m是n行m列,r,c是初始坐标,x是左移界限,y是右移界限
 57 void bfs()//主要操作
 58 {
 59     deque<node> a;//开个双端队列瞎搞一下
 60     a.push_back(node{r, c, 0, 0});//先把初始点压进去
 61     vis[r][c] = 1;//vis值记录为1
 62     while(!a.empty())//接下来的搜索流程
 63     {
 64         node b = a.front();//队列首部
 65         a.pop_front();//队列首部弹出
 66         for(int i = 0; i < 4; ++i)//for循环4个方向
 67         {
 68             int nx = b.x + d[i];//跑完的nx
 69             int ny = b.y + d[i + 4];//跑完的ny
 70             int nl = b.l, nr = b.r;//跑完的界限
 71             if(i == 0)//左移
 72             {
 73                 nl += 1;
 74             }
 75             if(i == 1)//右移
 76             {
 77                 nr += 1;
 78             }//下面是判断该点可行的条件:没有越出地图,是一个可标记的有效点,vis值为0,且nl,nr在左右移界限里(缺一不可)
 79             if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && mp[nx][ny] != '*' && vis[nx][ny] == 0 && nl <= x && nr <= y)
 80             {//确认该点可行
 81                 vis[nx][ny] = 1;//vis值赋为1
 82                 if(i == 0 || i == 1)
 83                     a.push_back(node{nx, ny, nl, nr});//如果该点是左右移动后得到的,压入队尾
 84                 else
 85                     a.push_front(node{nx, ny, nl, nr});//如果该点是上下移动后得到的,压入队首
 86             }
 87         }
 88     }
 89 }
 90  
 91 int main()
 92 {
 93     cin >> n >> m >> r >> c >> x >> y;
 94     repd(i, n)
 95     {
 96         repd(j, m)
 97         {
 98             cin >> mp[i][j];
 99         }
100     }
101     memset(vis, 0, sizeof(vis));//初始化vis值
102     bfs();//瞎搞一番,这时经过的点的vis值都变成了1
103     int cnt = 0;
104     repd(i, n)
105     {
106         repd(j, m)
107         {
108             cnt += vis[i][j];
109         }
110     }//累计一下和就好
111     cout << cnt << endl;
112     return 0;
113 }
114 /*========================================*/
115 //thank for your use.

第一次正儿八经的在比赛里写出BFS题,感觉还是不怎么熟练的。

猜你喜欢

转载自www.cnblogs.com/cloudplankroader/p/10349450.html
今日推荐