题目
Description
考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了’x’。
例如下图:
. . B x .
. x x A .
. . . x .
. x . . .
. . x . .
贝茜发现自己恰好在点A出,她想去B处的盐块添盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。
Input
行 1: 一个整数 N
行 2…N + 1: 行 i+1 有 N 个字符 (’.’, ‘x’, ‘A’, ‘B’),表示每个点的状态。
Output
行 1: 一个整数,最少的转弯次数。
Sample Input
3
.xA
…
Bx.
Sample Output
2
思路
听说这道题用暴搜+玄学的dir数组顺序可以AC但是我没试过
正解:BFS加一点记忆化。
而且需要注意的是,最短路径不代表最少转弯次数,后搜到的反而可能更优,当然也可能不,所以就需要添加记忆化搜索;
记忆化:用f[i][j][k]表示在(i,j)朝向方向k(0-3分别代表一个方向),每次改变k进行搜索,最后输出以终点为坐标,朝向四个方向的转弯次数的最小值就可以了。过程中打标记的vis数组也要开成三维的,不然不方便标记。
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,sx,sy,tx,ty,ans=0x3f3f3f3f; 4 char a[110][110],s[110]; 5 int f[110][110][4],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; 6 bool vis[110][110][4]; 7 // 0 1 2 3 8 //右 左 上 下 9 struct node 10 { 11 int x,y,dir; 12 }; 13 queue <node> q; 14 int min_(int a,int b,int c,int d) 15 { 16 if (a>b) a=b; 17 if (a>c) a=c; 18 if (a>d) a=d; 19 return a; 20 } 21 void init() 22 { 23 for(int i=0;i<110;i++) 24 for(int j=0;j<110;j++) 25 for(int k=0;k<4;k++) 26 f[i][j][k]=0x3f3f3f3f; 27 f[sx][sy][0]=0; 28 f[sx][sy][1]=0; 29 f[sx][sy][2]=0; 30 f[sx][sy][3]=0; 31 vis[sx][sy][0]=1; 32 vis[sx][sy][1]=1; 33 vis[sx][sy][2]=1; 34 vis[sx][sy][3]=1; 35 q.push((node){sx,sy,0}); 36 q.push((node){sx,sy,1}); 37 q.push((node){sx,sy,2}); 38 q.push((node){sx,sy,3}); 39 40 } 41 bool not_in(int x,int y) 42 { 43 return x<1||x>n||y<1||y>n||a[x][y]=='x'; 44 } 45 void bfs() 46 { 47 init(); 48 while(!q.empty()) 49 { 50 node now=q.front(); 51 q.pop(); 52 vis[now.x][now.y][now.dir]=false; 53 for (int i=0;i<4;i++) 54 { 55 int x=now.x+dx[i],y=now.y+dy[i]; 56 if(not_in(x,y))continue; 57 int l; 58 if(i==now.dir)l=0; 59 else l=1; 60 if (f[x][y][i]>f[now.x][now.y][now.dir]+l) 61 { 62 f[x][y][i]=f[now.x][now.y][now.dir]+l; 63 if(!vis[x][y][i]) 64 vis[x][y][i]=1,q.push((node){x,y,i}); 65 } 66 } 67 } 68 } 69 int main() 70 { 71 cin>>n; 72 for(int i=1;i<=n;i++) 73 { 74 for(int j=1;j<=n;j++) 75 { 76 cin>>a[i][j]; 77 if(a[i][j]=='A')sx=i,sy=j; 78 if(a[i][j]=='B')tx=i,ty=j; 79 } 80 } 81 bfs(); 82 ans=min_(f[tx][ty][0],f[tx][ty][1],f[tx][ty][2],f[tx][ty][3]); 83 if(ans!=0x3f3f3f3f) 84 cout<<ans<<endl; 85 else cout<<-1<<endl; 86 return 0; 87 }