1. 程式人生 > >獨輪車(廣搜狀態轉移的下一步伐的理解)

獨輪車(廣搜狀態轉移的下一步伐的理解)

Problem D

獨輪車

時限:1000ms 記憶體限制:10000K 總時限:3000ms

描述:

獨輪車的輪子上有紅、黃、藍、白、綠(依順時針序)5種顏色,在一個如下圖所示的20*20的迷宮內每走一個格子,輪子上的顏色變化一次。獨輪車只能向前推或在原地轉向。每走一格或原地轉向90度均消耗一個單位時間。現給定一個起點(S)和一個終點(T),求獨輪車以輪子上的指定顏色到達終點所需的最短時間。

輸入:

本題包含一個測例。測例中分別用一個大寫字母表示方向和輪子的顏色,其對應關係為:E-東、S-南、W-西、N-北;R-紅、Y-黃、B-藍、W-白、G-綠。在測試資料的第一行有以空格分隔的兩個整數和兩個大寫字母,分別表示起點的座標S(x,y)、輪子的顏色和開始的方向,第二行有以空格分隔的兩個整數和一個大寫字母,表示終點的座標T(x,y)和到達終點時輪子的顏色,從第三行開始的20行每行內包含20個字元,表示迷宮的狀態。其中'X'表示建築物,'.'表示路.

輸出:

在單獨的一行內輸出一個整數,即滿足題目要求的最短時間。

輸入樣例:

3 4 R N 15 17 Y XXXXXXXXXXXXXXXXXXXX X.X...XXXXXX......XX X.X.X.....X..XXXX..X X.XXXXXXX.XXXXXXXX.X X.X.XX....X........X X...XXXXX.X.XX.X.XXX X.X.XX....X.X..X.X.X X.X.X..XX...XXXX.XXX X.X.XX.XX.X....X.X.X X.X....XX.X.XX.X.X.X X.X.X.XXXXX.XX.X.XXX X.X.X.XXXXX....X...X X.X.......X.XX...X.X X.XXX.XXX.X.XXXXXXXX X.....XX.......X...X XXXXX....X.XXXXXXX.X X..XXXXXXX.XXX.XXX.X X.XX...........X...X X..X.XXXX.XXXX...XXX XXXXXXXXXXXXXXXXXXXX

輸出樣例:

56

來源:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define MAXN 210
char mapp[MAXN][MAXN];
int visit[MAXN][MAXN][6][6];
int dirx[4]={-1,1,0,0}; //上,下,左,右
int diry[4]={0,0,-1,1};
struct Node
{
	int x,y,color,dir,step;
};
queue<Node> q;
Node s,e;
int check(struct Node X)
{
	if(X.x<=0||X.x>20||X.y<=0||X.y>20||mapp[X.x][X.y]=='X'||visit[X.x][X.y][X.color][X.dir]==1)

    return 0;
    return 1;
}
int bfs()
{
	Node a,b;
	a.x=s.x,a.y=s.y,a.color=s.color,a.dir=s.dir,a.step=0;
	q.push(a);
	while(!q.empty())
	{
		a=q.front();
		q.pop();
		if(a.x==e.x&&a.y==e.y&&a.color==e.color) return a.step;  //return 是在pop的時候就return
        if(a.dir==0)
        {
            b=a; b.color=(a.color+1)%5;
            b.x=a.x-1;b.y=a.y;b.dir=a.dir;                      //step可以是step+1,也可是step+2 ,統稱為下一步伐,在一些情況下,step+2可能通過廣搜
            if(check(b))                                        //難找最短,要麼優先佇列,要麼將問題轉為step+1的情況
            {
                 visit[b.x][b.y][b.color][b.dir]=1;
                 b.step=a.step+1;
                 q.push(b);
            }
        }
        else if(a.dir==1)
        {
             b=a; b.color=(a.color+1)%5;
             b.x=a.x;b.y=a.y-1;b.dir=a.dir;
             if(check(b))
             {
                visit[b.x][b.y][b.color][b.dir]=1;
                b.step=a.step+1;
                q.push(b);
             }
        }
        else if(a.dir==2)
        {
            b=a; b.color=(a.color+1)%5;
            b.x=a.x+1; b.y=a.y; b.dir=a.dir;
            if(check(b))
            {
                visit[b.x][b.y][b.color][b.dir]=1;
                b.step=a.step+1;
                q.push(b);
            }
        }
        else if(a.dir==3)
        {
            b=a; b.color=(a.color+1)%5;
            b.x=a.x; b.y=a.y+1; b.dir=a.dir;
            if(check(b))
            {
                visit[b.x][b.y][b.color][b.dir]=1;
                b.step=a.step+1;
                q.push(b);
            }
        }
         b=a;  b.dir=(a.dir+1)%4;   if(check(b)) {visit[b.x][b.y][b.color][b.dir]=1; b.step=a.step+1; q.push(b);}  //原地轉動不變色
         b=a;  b.dir=(a.dir-1+4)%4; if(check(b)) {visit[b.x][b.y][b.color][b.dir]=1; b.step=a.step+1; q.push(b);}
	}
	return -1; //找不到輸出-1;
}
int main()
{
      int i,j;
      char a,b,c;
      scanf("%d %d %c %c",&s.x,&s.y,&a,&b);
      scanf("%d %d %c",&e.x,&e.y,&c);
      switch(a)
      {
          case 'R':s.color=0;break;
          case 'Y':s.color=1;break;
          case 'B':s.color=2;break;
          case 'W':s.color=3;break;
          case 'G':s.color=4;break;
      }
      switch(b)
      {
          case 'N':s.dir=0;break;
          case 'W':s.dir=1;break;
          case 'S':s.dir=2;break;
          case 'E':s.dir=3;break;
      }
       switch(c)
      {
          case 'R':e.color=0;break;
          case 'Y':e.color=1;break;
          case 'B':e.color=2;break;
          case 'W':e.color=3;break;
          case 'G':e.color=4;break;
      }
      for(i=1;i<=20;i++)
	  {
		  getchar();
		  for(j=1;j<=20;j++)
          scanf("%c",&mapp[i][j]);
	  }
	  memset(visit,0,sizeof(visit));
	  visit[s.x][s.y][s.color][s.dir]=1;
	  int ans=bfs();
	  printf("%d\n",ans);
	  return 0;
}