【JZOJ5793】小S練跑步【BFS】
阿新 • • 發佈:2018-11-09
題目大意:
題目連結:https://jzoj.net/senior/#main/show/5793
題目圖片:
http://wx1.sinaimg.cn/mw690/0060lm7Tly1fvx7ksrc55j30j20dw3z4.jpg
http://wx3.sinaimg.cn/mw690/0060lm7Tly1fvx7kss9v0j30jb0g1jro.jpg
思路:
P.S.本蒟蒻的語文不好,對於很難簡化的題目起不到什麼簡化所用。各位dalao就看題目圖片吧QWQ
正題:
很裸的廣搜啊。。。
對於一個點,向四個方向搜,直到遇到不能走的位置在停下。
例如:
就往四個方向列舉,直到四個方向都走到底為止。
那麼上圖能走的(能轉移的)被標記成紅色就是:
這也就是和普通廣搜的區別吧。。。
- 普通廣搜:每次往四個方向搜一個格子。
- 這道題:每次往四個方向搜到不能搜為止。
其實很像最小拐彎問題吧。
還有,這道題的
陣列也會有一個小變化。當我們搜到一個點
的
時,不要立刻
,因為可能會遇到如下情況:
藍色的塊從綠色的塊轉移來,
已經被標記。
我們現在要從紅色點往右搜,那麼
當我們搜到
時,如果直接退出,不繼續往後搜,那麼就會導致
的本來應該搜到的格子無法搜到。
所以就應該直接跳過已被標記的格子,直接跳到下一個
注意終點
也有可能是
。但是這種情況還是算可以到達的。記得先將終點的
去掉。
程式碼:
#include <cstdio>
#include <queue>
#include <ctime>
#include <cstring>
#include <iostream>
#define N 510
using namespace std;
const int dx[]={0,1,-1,0,0};
const int dy[]={0,0,0,1,-1};
const char way[]={' ','D','U','R','L'}; //四個方向
int n,m;
char c[N][N];
bool vis[N][N];
void bfs()
{
queue<int> x;
queue<int> y;
queue<int> dis;
vis[1][1]=1;
x.push(1);
y.push(1);
dis.push(-1);
while (x.size())
{
if (c[x.front()][y.front()]!='S')
for (int i=1;i<=4;i++)
{
if (c[x.front()][y.front()]==way[i]) continue;
int k=0;
while (1)
{
k++;
int xx=x.front()+k*dx[i];
int yy=y.front()+k*dy[i];
if (xx<1||yy<1||xx>n||yy>m) break;
if (c[xx][yy]=='S') break;
if (c[xx-dx[i]][yy-dy[i]]==way[i]) break;
if (vis[xx][yy]) continue;
vis[xx][yy]=1;
x.push(xx);
y.push(yy);
dis.push(dis.front()+1);
if (xx==n&&yy==m)
{
printf("%d",dis.front()+1);
return;
}
}
}
x.pop();
y.pop();
dis.pop();
}
printf("No Solution");
return;
}
int main()
{
cin>>n>>m;
if (n==1&&m==1)
{
printf("0");
return 0;
}
for (int i=1;i<=n;i++)
cin>>c[i]+1;
c[n][m]=' ';
bfs();
return 0;
}