本来没啥好说的,但细节实在比较多,被坑了好多次。

1.首先输入的是格子图,需要转化成点图,具体操作是a[][i=ai-1北-1] =a[][ -1]=ali-1][i]=1

2.最坑的一个点在于,平时写宽搜的时候,遇到出边界或者不能访问的点时,都是直接进入下一层循环(continue),但在这道题中,由于可以走1~3步,那么当路径上出现障碍时,则不能进行下一轮循环,需要break。

代码:
- #include <bits/stdc++.h>
- #define MAX 55
- using namespace std;
- int mod(int x){
- return (x+4)%4;
- }
- struct pt{
- int x, y, dir, step;
- pt(){}
- pt(int a, int b, int c, int d):x(a), y(b), dir(c), step(d){}
- };
- const int movx[] = {0,1,0,-1}, movy[] = {1,0,-1,0};
- int a[MAX][MAX];
- bool vis[MAX][MAX][5];
- int n, m;
- pt st, ed;
- void bfs(){
- queue<pt> q;
- bool flag = false;
- st.step = 0;
- q.push(st);
- vis[st.x][st.y][st.dir] = true;
- while(!q.empty()){
- pt t = q.front();
- q.pop();
- if(t.x == ed.x && t.y == ed.y){
- cout << t.step << endl;
- flag = true;
- break;
- }
- for(int i = 1; i <= 3; i++){
- int u, v;
- u = t.x + i*movx[t.dir];
- v = t.y + i*movy[t.dir];
- if(u<=0 || u>=n || v<=0 || v>=m || a[u][v] == 1){
- break;
- }
- if(vis[u][v][t.dir]){
- continue;
- }
- vis[u][v][t.dir] = true;
- q.push(pt(u, v, t.dir, t.step+1));
- }
- if(!vis[t.x][t.y][mod(t.dir+1)]){
- vis[t.x][t.y][mod(t.dir+1)] = true;
- q.push(pt(t.x, t.y, mod(t.dir+1), t.step+1));
- }
- if(!vis[t.x][t.y][mod(t.dir-1)]){
- vis[t.x][t.y][mod(t.dir-1)] = true;
- q.push(pt(t.x, t.y, mod(t.dir-1), t.step+1));
- }
- }
- if(!flag){
- cout << -1 << endl;
- }
- }
- int main()
- {
- cin >> n >> m;
- for(int i = 1; i <= n; i++){
- for(int j = 1; j <= m; j++){
- scanf("%d", &a[i][j]);
- if(a[i][j] == 1){
- a[i-1][j-1] = a[i-1][j] = a[i][j-1] = 1;
- }
- }
- }
- cin >> st.x >> st.y >> ed.x >> ed.y;
- char c;
- cin >> c;
- switch(c){
- case 'E':
- st.dir = 0; break;
- case 'S':
- st.dir = 1; break;
- case 'W':
- st.dir = 2; break;
- case 'N':
- st.dir = 3; break;
- }
- bfs();
- return 0;
- }

注:本文转载自他处,如有侵权,请联系作者删除。