当前位置: 代码迷 >> 综合 >> uva 816 abbott#39;s revenge ——yhx
  详细解决方案

uva 816 abbott#39;s revenge ——yhx

热度:7   发布时间:2024-01-13 12:02:56.0

看完题目的长度以后应该就知道这题有多变态了。。。

接下来你将看到代码的长度。。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 using namespace std;
  6 struct node
  7 {
  8     int x,y,d;
  9 }n1,n2,n3,par[15][15][5];
 10 char name[25];
 11 int xx[4]={-1,1,0,0},yy[4]={
   0,0,-1,1},start_x,start_y,end_x,end_y,start_d;
 12 bool to[15][15][5][5];
 13 bool ok(node n)
 14 {
 15     if (n.x>=1&&n.x<=9&&n.y>=1&&n.y<=9) return 1;
 16     return 0;
 17 } 
 18 int dir(char c)
 19 {
 20     if (c=='N') return 0;
 21     if (c=='S') return 1;
 22     if (c=='W') return 2;
 23     return 3;
 24 }
 25 int turn(int d,char t)
 26 {
 27     int x;
 28     if (t=='F') return d;
 29     if (t=='L')
 30     {
 31         if (d<2) return d+2;
 32         return 3-d;
 33     }
 34     if (d<2) return 3-d;
 35     return d-2;
 36 }
 37 void init()
 38 {
 39     int i,j,k,l,m,n,p,q,x,y,z;
 40     char s[50],c1,c2;
 41     scanf("%d%d %c %d%d",&start_x,&start_y,&c1,&end_x,&end_y);
 42     start_d=dir(c1);
 43     memset(to,0,sizeof(to));
 44     while (scanf("%d",&x)&&x)
 45     {
 46         scanf("%d ",&y);
 47         while (scanf("%c",&c1)&&c1!='*')
 48         {
 49             while (scanf("%c",&c2)&&c2!=' ')
 50               to[x][y][dir(c1)][turn(dir(c1),c2)]=1;
 51         }
 52     }
 53 }
 54 void prt(node n)
 55 {
 56     stack<node> sta;
 57     int cnt;
 58     while (n.x)
 59     {
 60         sta.push(n);
 61         n=par[n.x][n.y][n.d];
 62     }
 63     cnt=0;
 64     n1.x=start_x;
 65     n1.y=start_y;
 66     sta.push(n1);
 67     while (!sta.empty())
 68     {
 69         n1=sta.top();
 70         sta.pop();
 71         if (!(cnt%10)) printf(" ");
 72         printf(" (%d,%d)",n1.x,n1.y);
 73         if (++cnt%10==0) printf("\n");
 74     }
 75     if (cnt%10) printf("\n");
 76 }
 77 void solve()
 78 {
 79     int i,j,k,p,q;
 80     memset(par,0,sizeof(par));
 81     n1.x=start_x+xx[start_d];
 82     n1.y=start_y+yy[start_d];
 83     n1.d=start_d;
 84     queue<node> que;
 85     que.push(n1);      
 86     while (!que.empty())
 87     {
 88         n1=que.front();
 89         que.pop();
 90         if (n1.x==end_x&&n1.y==end_y) 
 91         {
 92             prt(n1);
 93             return;
 94         }
 95         for (i=0;i<=3;i++)
 96         {
 97             n2.x=n1.x+xx[i];
 98             n2.y=n1.y+yy[i];
 99             n2.d=i;
100             if (ok(n2)&&to[n1.x][n1.y][n1.d][i]&&(!par[n2.x][n2.y][n2.d].x))
101             {
102                 que.push(n2);
103                 par[n2.x][n2.y][n2.d]=n1;
104             }
105         }
106     }
107     printf("  No Solution Possible\n");
108 }
109 int main()
110 {
111     int i,j,k,p,q;
112     while (1)
113     {
114         scanf("%s",name);
115         if (name[0]=='E'&&name[1]=='N'&&name[2]=='D'&&strlen(name)==3) return 0;
116         init();
117         printf("%s\n",name);
118         solve();
119     }
120 }

无脑BFS+无脑的各种方向转换。

特别注意输出的各种回车空格。

用par数组记录父节点,顺便用来判重(如果没有父节点即为第一次搜到)。

据说用递归输出结果会栈溢出,于是用栈。注意虽然没有搜过起点,起点也要入栈。

每个状态有三个下标,位置和来自的方向。

读入比较复杂,但应该好理解。