营救公主解题思路与参考代码

maze

Time Limit:1000MS  Memory Limit:65536K Total Submit:290 Accepted:103

Description

500年前,Jesse是我国最卓越的剑客。他英俊潇洒,而且机智过人^_^。
突然有一天,Jesse心爱的公主被魔王抓走,并困在了一个巨大的迷宫中。Jesse听到这个消息,非常紧张。他知道公主在迷宫中还能坚持T个小时,他急忙赶到迷宫,开始到处寻找公主的下落。
Jesse会为你提供迷宫的地图以及所剩的时间T。请你判断他是否能在所剩的时间内找到心爱的公主。

Input

题目包括多组测试数据。 每组测试数据以三个整数N,M,T(00)开头,分别代表迷宫的长和高,以及公主能坚持的小时数。 紧接着有M行,N列字符,由".","*","P","S"组成。 其中 "." 代表能够行走的空地。 "*" 代表墙壁,Jesse不能从此通过。 "P" 是公主所在的位置。 "S" 是Jesse的起始位置。 每次Jesse只能选择“上、下、左、右”任意一个方向走一步。 每走一步花费1个小时。 输入以0 0 0结束。

Output

如果能在规定时间内救出公主输出“YES”,否则输出“NO”。

Sample Input

4 4 10
....
....
....
S**P
0 0 0

 

 

Sample Output

YES

 

 

Hint

测试样例中,王子从S点,上 右 右 右 下,一共花了五个小时刚好找到公主所在的P点

Source

参考代码1
 1 #include "iostream"
 2 using namespace std;
 3 char map[1011][1011]; //地图数组
 4 int res[1011][1011];   //步数数组,每个元素代表走到该点需要的步数
 5 struct point   //队列,由于是二维地图,所以队列有两个元素  横纵坐标
 6 {
 7     int x,y;
 8 }r[1011];
 9 
10 int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}};   //四个遍历方向
11 
12 int main()
13 {
14      int i,j,n,m,time,max;
15     int si,sj,pi,pj,head,tail,x1,y1;
16     while(scanf("%d%d%d",&m,&n,&time)!=EOF&&n||m||time)
17     {
18           for(i=0; i<=m+1; i++)
19               map[0][i]=map[n+1][i]='*';
20           for(i=0; i<=n+1; i++)
21               map[i][0]=map[i][m+1]='*';
22               
23         for(i=1; i<=n; i++)  //初始化一个边框
24             for(j=1; j<=m; j++)
25             {
26                 cin>>map[i][j];
27                 res[i][j]=-1;
28                 if(map[i][j]=='S')
29                 {
30                     si=i, sj=j;
31                     res[i][j]=0;
32                     }
33                 if(map[i][j]=='P')
34                     pi=i, pj=j;
35             }
36         r[0].x=si,r[0].y=sj;
37         tail=1, head=0;        
38           while(tail != head)
39         {
40                x1=r[head].x,y1=r[head].y;
41              for(i=0; i<4; i++)
42             {
43                     x1+=dis[i][0], y1+=dis[i][1];
44                 if((map[x1][y1]=='.'|| 
45                        map[x1][y1]=='P')&&
46                        res[x1][y1]==-1) //满足条件,则该点入队列
47                 {
48                     r[tail].x=x1;
49                     r[tail].y=y1;
50                     res[x1][y1] = 1 + res[x1-dis[i][0]][y1-dis[i][1]];
51                     tail++;
52                 }
53             
54                 x1-=dis[i][0], y1-=dis[i][1];
55             }
56              head++;    
57         }
58         for(i=1; i<=n; i++)
59         {
60             for(j=1; j<=m; j++)
61                 cout<" ";
62               cout<<endl;
63           }
64           if(res[pi][pj]<=time && res[pi][pj]!=-1)
65             printf("YES/n");
66           else
67               printf("NO/n");
68     }
69     system("pause");
70     return 0;
71 }
72 
73 /*广度优先搜索的基本思想是:
74 (1)从图中某个顶点V0出发,首先访问V0。
75 (2)依次访问V0的各个未被访问的邻节点。
76 (3)分别从这些邻节点出发,依次访问它们的各个未被访问的邻节点 
77 */
参考代码2
 1 #include 
 2 #include 
 3 using namespace std;
 4 struct queue
 5 {
 6     int X,Y;
 7 };
 8 queue all[10002];
 9 char A[103][103];
10 int B[103][103];
11 int fang[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
12 int main()
13 {
14     int i,j,k,q,p,n,m,x,y,step,t;
15     int reat,front;queue go;char ppp;
16     while (scanf("%d%d%d",&n,&m,&t) != EOF)
17     {  
18         if (n ==0&&m == 0&&t==0) 
19          break;
20         for (i = 0;i <= n+1;i++)
21         {    A[0][i] = A[m+1][i] = '*';
22              B[0][i] = B[m+1][i] = -1;
23         }
24         for (i = 0;i <= m+1;i++)
25         {    A[i][0] = A[i][n+1] = '*';
26              B[i][0] = B[i][n+1] = -1;
27         }
28         reat = front = 0;
29         for (i = 1;i <= m;i++)
30         {
31             for (j = 1;j <= n;j++)
32             {//cin>>A[i][j];
33                 B[i][j] = -1;
34                scanf("%c",& A[i][j]);
35                // scanf("%c",&A[i][j]);
36                 if (A[i][j] == 'S')
37                 {
38                     all[reat].X = i;
39                     all[reat].Y = j;
40                     B[i][j] = 0;
41                     reat++;
42                 }
43                 else if(A[i][j] == 'P')
44                 {
45                     go.X = i;
46                     go.Y = j;
47                 }
48             }
49         }
50         while (front != reat)
51         {
52             x = all[front].X;
53             y = all[front].Y;  step = B[x][y];
54             for (i = 0;i < 4;i++)
55             {
56               
57                 x += fang[i][0];
58                 y += fang[i][1];
59                 if ((A[x][y] == '.'||A[x][y] == 'P')&&B[x][y] == -1)
60                 {
61                     all[reat].X = x;
62                     all[reat].Y = y;
63                     B[x][y] = step + 1;
64                     reat++;
65                 }
66                 x -= fang[i][0];
67                 y -= fang[i][1];
68             }
69             front++;
70         }
71         if (B[go.X][go.Y] <= t&&B[go.X][go.Y] != -1)
72             printf("YES\n");
73         else
74             printf("NO\n");
75     }
76     return 0;
77 }
参考代码3
  1 #include 
  2 using namespace std;
  3 
  4 #include 
  5 #include 
  6 const int INIT_SIZE = 10000;
  7 ///==========================queue========================
  8 template 
  9 class Queue
 10 {
 11 private:
 12   T _queue[INIT_SIZE];
 13   int front,rear;
 14 public:
 15   Queue();
 16   bool EnQueue(T e);     //入队
 17   bool DeQueue(T &e);    //出队
 18   inline bool IsEmpty();
 19 };
 20 
 21 template 
 22 Queue::Queue()
 23 {
 24   front = rear = 0;
 25 }
 26 
 27 template 
 28 bool Queue::EnQueue(T e)
 29 {
 30   if((rear + 1) % INIT_SIZE == front)
 31     return false;
 32   _queue[rear] = e;
 33   rear = (rear + 1) % INIT_SIZE;
 34   return true;
 35 }
 36 
 37 template 
 38 bool Queue::DeQueue(T &e)
 39 {
 40   if(front == rear)
 41     return false;
 42   e = _queue[front];
 43   front = (front + 1)%INIT_SIZE;
 44   return true;
 45 }
 46 
 47 template 
 48 inline bool Queue::IsEmpty()
 49 {
 50   return rear == front;
 51 }
 52 ///=======================================================
 53 struct Coordinate
 54 {
 55   int x,y;
 56 };
 57 
 58 class RescueThePrincess
 59 {
 60 private:
 61   int N,M,T;  //N,M迷宫的长和高;T公主能存活的天数
 62   int **mazeGraphics;//输入的迷宫图
 63   struct Coordinate cavalier,princess;//
 64 public:
 65   RescueThePrincess();//初始化迷宫图
 66   ~RescueThePrincess();
 67   void DisplayMazeGraphics();
 68   bool FindTheShortestPath();//寻找解救公主的最短路径
 69 }  ;
 70 
 71 RescueThePrincess::RescueThePrincess()
 72 {
 73   cin>>N>>M>>T;
 74   getchar();
 75   if(N == 0 && M == 0 && T == 0)
 76     exit(EXIT_FAILURE);
 77   mazeGraphics = (int**)calloc(M,sizeof(int*));
 78   for(int i = 0; i < M; ++i)
 79     {
 80       mazeGraphics[i] = (int*)calloc(N,sizeof(int));
 81       for(int j = 0; j < N; ++j)
 82         {
 83           char cTemp;
 84           cin>>cTemp;
 85           switch(cTemp)
 86             {
 87             case '.':
 88               mazeGraphics[i][j] = 0; //可通过
 89               break;
 90             case '*':
 91               mazeGraphics[i][j] = -1;//
 92               break;
 93             case 'P':
 94               mazeGraphics[i][j] = 0; //公主的位置
 95               princess.x = j;
 96               princess.y = i;
 97               break;
 98             case 'S':
 99               mazeGraphics[i][j] = 0; //骑士的位置
100               cavalier.x = j;
101               cavalier.y = i;
102               break;
103             default:
104               exit(EXIT_FAILURE);
105             }
106         }
107       getchar();
108     }
109 }
110 
111 RescueThePrincess::~RescueThePrincess()
112 {
113   for(int i = 0; i < M; ++i)
114     free(mazeGraphics[i]);
115   free(mazeGraphics);
116   mazeGraphics = NULL;
117 }
118 
119 void RescueThePrincess::DisplayMazeGraphics()
120 {
121   for(int i = 0; i < M; i++)
122     {
123       for(int j = 0; j < N; ++j)
124         cout<' ';
125       cout<<endl;
126     }
127 }
128 bool RescueThePrincess::FindTheShortestPath()
129 {
130   Queue Q;
131   Q.EnQueue(cavalier);
132   while(!Q.IsEmpty())
133     {
134       Coordinate e;
135       Q.DeQueue(e);
136       if(e.y - 1 >= 0 && mazeGraphics[e.y - 1][e.x] != -1) //shang
137         {
138           if(mazeGraphics[e.y - 1][e.x] > (mazeGraphics[e.y][e.x] + 1) || mazeGraphics[e.y - 1][e.x] == 0)
139             {
140               mazeGraphics[e.y - 1][e.x] = mazeGraphics[e.y][e.x] + 1;
141               Coordinate temp;
142               temp.x = e.x;
143               temp.y = e.y - 1;
144               Q.EnQueue(temp);
145             }
146         }
147       if(e.x + 1 < N && mazeGraphics[e.y][e.x + 1] != -1) //you
148         {
149           if(mazeGraphics[e.y][e.x + 1] > (mazeGraphics[e.y][e.x] + 1) || mazeGraphics[e.y][e.x + 1] == 0)
150             {
151               mazeGraphics[e.y][e.x + 1] = mazeGraphics[e.y][e.x] + 1;
152               Coordinate temp;
153               temp.x = e.x + 1;
154               temp.y = e.y;
155               Q.EnQueue(temp);
156             }
157         }
158       if(e.y + 1 < M && mazeGraphics[e.y + 1][e.x] != -1) //xia
159         {
160           if(mazeGraphics[e.y + 1][e.x] > (mazeGraphics[e.y][e.x] + 1) || mazeGraphics[e.y + 1][e.x] == 0)
161             {
162               mazeGraphics[e.y + 1][e.x] = mazeGraphics[e.y][e.x] + 1;
163               Coordinate temp;
164               temp.x = e.x;
165               temp.y = e.y + 1;
166               Q.EnQueue(temp);
167             }
168         }
169       if(e.x - 1 >= 0 && mazeGraphics[e.y][e.x - 1] != -1) //zuo
170         {
171           if(mazeGraphics[e.y][e.x - 1] > (mazeGraphics[e.y][e.x] + 1) || mazeGraphics[e.y][e.x - 1] == 0)
172             {
173               mazeGraphics[e.y][e.x - 1] = mazeGraphics[e.y][e.x] + 1;
174               Coordinate temp;
175               temp.x = e.x - 1;
176               temp.y = e.y;
177               Q.EnQueue(temp);
178             }
179         }
180 
181     }
182   if(mazeGraphics[princess.y][princess.x] != 0 && mazeGraphics[princess.y][princess.x] <= T - 2)
183     return true;
184   else
185     return false;
186 }
187 
188 int main(void)
189 {
190   while(true)
191     {
192       RescueThePrincess* problem = new RescueThePrincess();
193       if(problem->FindTheShortestPath())
194         cout<<"YES"<<endl;
195       else
196         cout<<"NO"<<endl;
197       problem->~RescueThePrincess();
198     }
199   return 0;
200 }

 

参考代码4
  1 #include
  2 #include<string.h> 
  3 #define E  'P'  //目的地标记
  4 #define S  'S' 
  5 struct 
  6 {    
  7 int x,y;
  8 }start;
  9 struct 
 10 {    
 11 int x,y;
 12 }end;
 13 char m[26][26];
 14 char arr[26][26];
 15 int ri[5]={0,1,0,-1,0},ci[5]={0,0,1,0,-1},k,k2,t;
 16 int succ=0;//所走方向  先向下 逆时针//墙壁是#,走过的路径为*,走过退回来的为@
 17 void maze(int k,int r,int c);//记录走过的步数
 18 int main()
 19 {    
 20 int r,c,qc;    
 21 int i,j;    
 22 memset(arr,0,sizeof(arr));   
 23 while
 24 (
 25 scanf("%d%d%d",&c,&r,&t),r||c||t)    
 26 {        
 27 k=0;       
 28  k2=0;       
 29  succ=0;                
 30  for(i=1;i<=r;i++)       
 31  {           
 32  m[1][0]='#';           
 33  scanf("%s",&m[i][1]);            //
 34  printf("%s\n",&m[i][1] );        
 35  }                        
 36  qc = strlen(m[1]);        //搜索出开始点和结束点        
 37  for(i=1;i<=r;i++)        
 38  {            
 39  for(j=1;j)           
 40  {                
 41  if(m[i][j]==S)                
 42  {                   
 43  start.x=i;                    
 44  start.y=j;                                    
 45  }                
 46  if(m[i][j]==E)               
 47  {                    
 48  end.x=i;                    
 49  end.y=j;                
 50  }            
 51  }        
 52  }       
 53  arr[end.x][end.y]=E;        //铺设外围墙壁        
 54  for(j=0;j<=r+1;j++)        
 55  {            
 56  m[j][0]='#';            
 57  m[j][qc]='#';            
 58  m[j][qc+1]='\0';                    
 59  }        
 60  for(j=0;j<=qc;j++)        
 61  {            
 62  m[0][j]='#';            
 63  m[r+1][j]='#';        
 64  }        //铺设完毕    //    
 65  for(i=0;i<=r+1;i++)    //    
 66  {            //        
 67  printf("%s\n",m[i]);                //   
 68  }    //    
 69  printf("%d %d\n",end.x,end.y);    //   
 70  printf("%d %d\n",start.x,start.y);        
 71  maze(k,start.x,start.y);            
 72  if(succ==1&&(k2+1)<=t)           
 73  printf("YES\n");        
 74  else            
 75  printf("NO\n");        
 76  arr[end.x][end.y]=0;    
 77  }    
 78  return 0;
 79  }//严蔚敏演示系统里经典递归
 80  void maze(int k,int r,int c)//记录走过的步数
 81  {    
 82  int i;        
 83  if(m[r][c]!='*'&&m[r][c]!='#'&&m[r][c]!='@')    
 84  {             
 85  m[r][c]='*';        
 86  if(arr[r][c]==E)        
 87  {           
 88  succ=1;       
 89  }       
 90  else        
 91  {            
 92  i=0;            
 93  while(!succ&&i<4)            
 94  {                
 95  i++;            //   
 96  printf("r=%d c= %d k= %d\n",r,c,k );                
 97  k2=k;                
 98  if(k<t)                    
 99  maze(k+1,r+ri[i],c+ci[i]);            
100  }        
101  }
102  if(!succ) m[r][c] = '@';                
103  //printf("(2)r=%d c= %d\n",r,c);    
104  }
105  }

 

转载于:https://www.cnblogs.com/alanlau2011/archive/2012/07/15/2592545.html

你可能感兴趣的:(营救公主解题思路与参考代码)