USACO-2017-JAN-金组 Cow Navigation

来源:互联网 发布:金英杰免费网络课登录 编辑:程序博客网 时间:2024/06/05 02:46

。## 题目 ##
Bessie has gotten herself stuck on the wrong side of Farmer John’s barn again, and since her vision is so poor, she needs your help navigating across the barn.
The barn is described by an N×N grid of square cells (2≤N≤20), some being empty and some containing impassable haybales. Bessie starts in the lower-left corner (cell 1,1) and wants to move to the upper-right corner (cell N,N). You can guide her by telling her a sequence of instructions, each of which is either “forward”, “turn left 90 degrees”, or “turn right 90 degrees”. You want to issue the shortest sequence of instructions that will guide her to her destination. If you instruct Bessie to move off the grid (i.e., into the barn wall) or into a haybale, she will not move and will skip to the next command in your sequence.

Unfortunately, Bessie doesn’t know if she starts out facing up (towards cell 1,2) or right (towards cell 2,1). You need to give the shortest sequence of directions that will guide her to the goal regardless of which case is true. Once she reaches the goal she will ignore further commands.

输入

The first line of input contains N.
Each of the N following lines contains a string of exactly N characters, representing the barn. The first character of the last line is cell 1,1. The last character of the first line is cell N, N.

Each character will either be an H to represent a haybale or an E to represent an empty square.

It is guaranteed that cells 1,1 and N,N will be empty, and furthermore it is guaranteed that there is a path of empty squares from cell 1,1 to cell N,N.

输出

On a single line of output, output the length of the shortest sequence of directions that will guide Bessie to the goal, irrespective whether she starts facing up or right.

样例输入

3
EHE
EEE
EEE

样例输出

9

提示

In this example, the instructions “Forward, Right, Forward, Forward, Left, Forward, Left, Forward, Forward” will guide Bessie to the destination irrespective of her starting orientation.


题意

   一共有两头牛,一个n*n的矩阵,两头牛的初始位置都是(n,1)不知道是面朝(n-1,1)还是(n,2),题目给定图,E可以走,H有障碍物。   一共有三种指令,向左转,向右转,向前走,两头牛是同时接受消息,并同步执行命令,但是因为初始的方向不同,走过的路径也不同。   但当牛面朝矩阵边界,或者面朝内容为’H'的位置时可以发出向前走的命令,但是牛不执行。(总不能让牛钻进草堆里吧)   问题就是,最少要下达多少次命令才可以让两头牛同时在(1,n)的位置。(都在(1,n)时面向方向无所谓。)   其中,转向并走一步算是两条命令。

思路

 我一开始非常倔强的用普通的BFS写,一个结构体里放两头牛,同时执行发出的命令,写了没多久,调试调了两天也调出来。 姑且先把代码贴出来,等大神帮看看。 最后还是从网上找的题解,写的六维BFS。 每头牛的位置(x,y)方向(z)三个量,两头牛,所以就是一个六维的数组。 再就是BFS一下下就好了。 附上代码:
//自己写的WA的代码#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <math.h>#include <map>#define  mem(a)  memset(a,0,sizeof(a))using namespace std;struct node{    int x,y;//postion   right    int z;  //direction   //up 2   left 1  right 3  down 0    int a,b;//postion   up    int c;  //direction   //up 2   left 1  right 3  down 0    int step;    friend bool operator < (node ff,node gg)    {    if(gg.step!=ff.step)        return gg.step<ff.step;    else        return gg.x  < ff.x;    }} ;int d;char c;node a[25][25];node n,t;//bool vis1[25][25][4];//xyz//bool vis2[25][25][4];//abcbool vis[25][25][25][25][4][4];int p[4][2]= {1,0,0,-1,-1,0,0,1};bool HHH[25][25];void inti (){    cin>>d;    mem(vis);    for(int i=0; i<d; ++i)        for(int j=0; j<d; ++j)        {            cin>>c;            if(c=='H')            {                for(int k=0; k<4; ++k )                    for(int l=0; l<4; ++l)                        vis[i][j][i][j][k][l] = true;                HHH[i][j]=true;            }            else                HHH[i][j] = false;        }    for(int k=0; k<4; ++k )        for(int l=0; l<4; ++l)            vis[d-1][0][d-1][0][k][l] = true;}inline void judge_direction (){    if(t.c<0) t.c+=4;    if(t.z<0) t.z+=4;    t.c%=4;    t.z%=4;}inline void next_step (int d1,int d2){    int x1=t.x,x2=t.a,y1=t.y,y2=t.b;    if(t.x+p[d1][0]>=0 && t.x+p[d1][0]<d && t.y+p[d1][1]>=0 && t.y+p[d1][1]<d  )    {        if(!HHH[t.x+p[d1][0]][t.y+p[d1][1]])        {            x1=t.x+p[d1][0];            y1=t.y+p[d1][1];        }    }    if(t.a+p[d2][0]>=0 && t.a+p[d2][0]<d && t.b+p[d2][1]>=0 && t.b+p[d2][1]<d)    {        if(!HHH[t.a+p[d2][0]][t.b+p[d2][1]])        {            x2=t.a+p[d2][0];            y2=t.b+p[d2][1];        }    }    if(vis[x1][y1][x2][y2][t.z][t.c]!=true)    {        vis[x1][y1][x2][y2][t.z][t.c]=true;        t.x=x1;        t.y=y1;        t.a=x2;        t.b=y2;    }//    if(vis1[t.x+p[d1][0]][t.y+p[d1][1]][t.z]!=true || vis2[t.a+p[d2][0]][t.b+p[d2][1]][t.c]!=true)//    {//        if(t.x+p[d1][0]>=0 && t.x+p[d1][0]<d && t.y+p[d1][1]>=0 && t.y+p[d1][1]<d)//        {//            vis1[t.x+p[d1][0]][t.y+p[d1][1]][t.z]=true;//            t.x+=p[d1][0];//            t.y+=p[d1][1];//        }//        if(t.a+p[d2][0]>=0 && t.a+p[d2][0]<d && t.b+p[d2][1]>=0 && t.b+p[d2][1]<d)//        {//            vis2[t.a+p[d2][0]][t.b+p[d2][1]][t.c]=true;//            t.a+=p[d2][0];//            t.b+=p[d2][1];//        }//    }}inline bool judge (){    if(t.a!=n.a||t.b!=n.b||t.x!=n.x||t.y!=n.y)        return true;    return false;}void bfs (){    priority_queue <node> s;    n.a=d-1;    n.b=0;    n.c=2;    n.x=d-1;    n.y=0;    n.z=3;    n.step=0;    s.push(n);    while(!s.empty())    {        n=s.top();        s.pop();        if(n.x==0 && n.y==d-1 && n.a==0 && n.b==d-1)        {            cout<<n.step<<endl;            break;        }        //go stright        t=n;        t.step++;        next_step(t.z,t.c);        if(judge())            s.push(t);        //turn right        t=n;        t.c++;        t.z++;        t.step+=2;        judge_direction();        next_step(t.z,t.c);        if(judge())            s.push(t);        //turn left        t=n;        t.c--;        t.z--;        t.step+=2;        judge_direction();        next_step(t.z,t.c);        if(judge())            s.push(t);//        //turn right  turn right//        t=n;//        t.c+=2;//        t.z+=2;//        t.step+=3;//        judge_direction();//        next_step(t.z,t.c);//        if(judge())//        {//            remember1[t.x][t.y] = t.step;//            remember2[t.a][t.b] = t.step;//            s.push(t);//        }    }}int main (){#ifndef ONLINE_JUDGE    freopen("1","r",stdin);#endif // ONLINE_JUDGE    ios_base::sync_with_stdio(false);    cin.tie(0);    inti();    bfs();    return 0;}/**************************************************************    Language: C++    Result: 答案错误****************************************************************/
//题解里的六维BFS代码#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define maxn 25#define mem(a) memset(a,0,sizseof(a))using namespace std;int n,map[maxn][maxn],dis[maxn][maxn][maxn][maxn][5][5];char s[maxn];int dx[]={0,-1,0,1,0},dy[]={0,0,1,0,-1};bool vis[maxn][maxn][maxn][maxn][5][5];struct node{    int x1,x2,y1,y2,d1,d2;    node (int x1,int y1,int x2,int y2,int d1,int d2):x1(x1),y1(y1),x2(x2),y2(y2),d1(d1),d2(d2) {}    node () {}};bool judge(int x,int y){    return ((x>=1) && (x<=n) && (y>=1) && (y<=n));}void bfs(){    queue <node> q;    q.push(node(n,1,n,1,1,2));    while (!q.empty())    {        node head=q.front();q.pop();        int nx1,nx2,ny1,ny2;        nx1=head.x1+dx[head.d1];nx2=head.x2+dx[head.d2];ny1=head.y1+dy[head.d1];ny2=head.y2+dy[head.d2];        int t2=dis[head.x1][head.y1][head.x2][head.y2][head.d1][head.d2];        if ((!judge(nx1,ny1)) || (!map[nx1][ny1])) nx1=head.x1,ny1=head.y1;        if ((!judge(nx2,ny2)) || (!map[nx2][ny2])) nx2=head.x2,ny2=head.y2;        if ((head.x1==1) && (head.y1==n)) nx1=1,ny1=n;        if ((head.x2==1) && (head.y2==n)) nx2=1,ny2=n;        int &t1=dis[nx1][ny1][nx2][ny2][head.d1][head.d2];        if (t1>t2+1)        {            t1=t2+1;            bool &t3=vis[nx1][ny1][nx2][ny2][head.d1][head.d2];            if (!t3)            {                t3=true;                q.push(node(nx1,ny1,nx2,ny2,head.d1,head.d2));            }        }        int dd1,dd2;        dd1=head.d1-1;dd2=head.d2-1;if (!dd1) dd1=4;if (!dd2) dd2=4;        int &t5=dis[head.x1][head.y1][head.x2][head.y2][dd1][dd2];        if (t5>t2+1)        {            t5=t2+1;            bool &t3=vis[head.x1][head.y1][head.x2][head.y2][dd1][dd2];            if (!t3)            {                t3=true;                q.push(node(head.x1,head.y1,head.x2,head.y2,dd1,dd2));            }        }        dd1=head.d1+1;dd2=head.d2+1;if (dd1==5) dd1=1;if (dd2==5) dd2=1;        int &t4=dis[head.x1][head.y1][head.x2][head.y2][dd1][dd2];        if (t4>t2+1)        {            t4=t2+1;            bool &t3=vis[head.x1][head.y1][head.x2][head.y2][dd1][dd2];            if (!t3)            {                t3=true;                q.push(node(head.x1,head.y1,head.x2,head.y2,dd1,dd2));            }        }    }}int main(){#ifndef ONLINE_JUDGE    freopen("1","r",stdin);#endif // ONLINE_JUDGE    ios_base::sync_with_stdio(false);    cin.tie(0);    scanf("%d",&n);memset(dis,0x3f,sizeof(dis));    for (int i=1;i<=n;i++)    {        scanf("%s",s);        for (int j=0;j<n;j++)        {            if (s[j]=='E')                map[i][j+1]=1;        }    }    dis[n][1][n][1][1][2]=0;    bfs();    int mn=1<<29;    for (int i=1;i<=4;i++)        for (int j=1;j<=4;j++)            mn=min(mn,dis[1][n][1][n][i][j]);    printf("%d\n",mn);    return 0;}/**************************************************************    Language: C++    Result: 正确    Time:132 ms    Memory:49788 kb****************************************************************/