USACO 2017 January Contest Gold T3: Cow Navigation

题目大意

贝西误把自己困在了FJ谷仓的一侧。因为她的视力很差,她在脱困时需要你的帮助。

谷仓的平面图是一个方格图,有些方格(即单位)是空的,其他的则是不可通过的柴草堆。贝西从左下角开始(方格1,1)想一路搬到右上角。你可以引导她,告诉她一个指令序列,指令可以为“前进”“左转90度”“右转90度”。你需要得出能够使她到达目的地所用的最短指令序列。如果你指示贝西离开谷仓或至柴草堆,她不会移动,会直接跳到下一个命令序列。

不幸的是,贝西不知道她一开始所朝的方向(可能是上或右),而序列无需考虑这种情况,(使得bessie无论是朝上还是朝右,根据给出的指令都能到达终点。)

注意:到了终点就不会再移动了

 (2N20)

题目分析

因为N很小,而对于此题,我们什么都不知道,所以考虑搜索。

因为一开始不知道是向上还是向右,所以我们的vis数组要开六维,分别记录一开始向上或向右的情况。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=25;
 4 
 5 int dx[5]={-1,0,1,0};
 6 int dy[5]={0,1,0,-1};
 7 
 8 int n;
 9 bool blk[MAXN][MAXN],vis[MAXN][MAXN][4][MAXN][MAXN][4];
10 int dis[MAXN][MAXN][4][MAXN][MAXN][4];
11 struct Node{
12     int x,y,d;
13     inline bool Ok(){return x>=1&&x<=n&&y>=1&&y<=n&&!blk[x][y];}
14 };
15 struct q_Node{
16     Node p1,p2;
17     void mrk(){vis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d]=true;}
18     bool IsMrked(){return vis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d];}
19     int &get(){return dis[p1.x][p1.y][p1.d][p2.x][p2.y][p2.d];}
20 }q1,p,nxt;
21 queue<q_Node> q;
22 inline void Move(Node &d,Node f,int w){
23     d=f;
24     if(w==0){
25         if(d.x==1&&d.y==n) return;
26         d.x+=dx[d.d];
27         d.y+=dy[d.d];
28         if(!d.Ok()) d=f;
29     }
30     else if(w==1){
31         ++d.d;
32         if(d.d==4) d.d=0;
33     }
34     else if(w==2){
35         --d.d;
36         if(d.d==-1) d.d=3;
37     }
38 }
39 int main(){
40     memset(dis,0x3f,sizeof(dis));
41     scanf("%d",&n);
42     for(int i=1;i<=n;++i){
43         getchar();
44         for(int j=1;j<=n;++j)
45             blk[i][j]=(getchar()=='H');
46     }
47     q1.p1.x=q1.p2.x=n;
48     q1.p1.y=q1.p2.y=q1.p2.d=1;
49     q1.get()=0;
50     q.push(q1);
51     while(!q.empty()){
52         p=q.front();
53         q.pop();
54         int w=p.get();
55         for(int i=0;i<3;++i){
56             Move(nxt.p1,p.p1,i);
57             Move(nxt.p2,p.p2,i);
58             int &nd=nxt.get();
59             if(nd>w+1){
60                 nd=w+1;
61                 if(!nxt.IsMrked()){
62                     q.push(nxt);
63                     nxt.mrk();
64                 }
65             }
66         }
67     }
68     int ans=0x3f3f3f3f;
69     for(int i=0;i<4;++i)
70         for(int j=0;j<4;++j)
71             ans=min(ans,dis[1][n][i][1][n][j]);
72     printf("%d\n",ans);
73     return 0;
74 }

猜你喜欢

转载自www.cnblogs.com/LI-dox/p/11228397.html