这一题在左右移动距离上给出了限制,总结下来,就是在上下移动不限,左右移动有界的情况下求出能走到的最多的格子。
我是用了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题,感觉还是不怎么熟练的。