【题解】[USACO2007 OCT]Obstacle Course-C++

题目
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 }
个人博客地址: www.moyujiang.com 或 moyujiang.top
原文地址:https://www.cnblogs.com/moyujiang/p/11213604.html