HDU 1728 逃离迷宫

Problem Description

  给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?

Input

  第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
  第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。

Output

  每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。

Sample Input

2
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3

Sample Output

no
yes

Source

“网新恩普杯”杭州电子科技大学程序设计邀请赛
 
 
先上一段TLE代码
 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,T,ex,ey;//T表示最大转弯次数,e表示终点
 6 char a[105][105];
 7 int rx[]={0,0,1,-1};
 8 int ry[]={1,-1,0,0};
 9 bool vis[105][105];
10 struct node
11 {
12     int x,y,turn,dir;//turn表示次数,dir表示方向
13 }per;
14 bool check(node b)
15 {
16     if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=m&&a[b.x][b.y]!='*')
17         if(!vis[b.x][b.y])
18             if(b.turn<=T)
19                 return true;
20     return false;
21 }
22 bool bfs()
23 {
24     queue<node>Q;
25     Q.push(per);
26     node cur,next;
27     while(!Q.empty())
28     {
29         cur=Q.front();
30         Q.pop();
31         vis[cur.x][cur.y]=true;
32         if(cur.x==ex&&cur.y==ey&&cur.turn<=T)
33             return true;
34         if(cur.turn>T)
35             break;
36         for(int i=0;i<4;i++)
37         {
38             next.x=cur.x+rx[i];
39             next.y=cur.y+ry[i];
40             next.dir=i;
41             next.turn=cur.turn;
42             if(next.dir!=cur.dir&&cur.dir!=-1)
43                 next.turn++;
44             if(check(next))
45                 Q.push(next);
46         }
47     }
48     return false;
49 }
50 int main()
51 {
52     int K;
53     cin>>K;
54     while(K--)
55     {
56         cin>>n>>m;
57         for(int i=1;i<=n;i++)
58         {
59             for(int j=1;j<=m;j++)
60             {
61                 cin>>a[i][j];
62             }
63         }
64         cin>>T>>per.y>>per.x>>ey>>ex;//这里注意是先列后行
65         per.turn=0;
66         per.dir=-1;
67         memset(vis,false,sizeof(vis));
68         if(bfs())cout<<"yes"<<endl;
69         else cout<<"no"<<endl;
70     }
71     return 0;
72 }

 因为以转弯数为判断条件,所以要尽量少地改变方向,就像之前做迷宫以步数为条件时,尽可能地减少步数一样,所以采取在一个方向上搜到底的方法。

AC代码如下,就是上面直接改了一下,有些不必要的码也在里面懒得改orz

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,T,ex,ey;//T表示最大转弯次数,e表示终点
 6 char a[105][105];
 7 int rx[]={0,0,1,-1};
 8 int ry[]={1,-1,0,0};
 9 bool vis[105][105];
10 struct node
11 {
12     int x,y,turn,dir;//turn表示次数,dir表示方向
13 }per;
14 bool check(node b)
15 {
16     if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=m&&a[b.x][b.y]!='*')
17         if(!vis[b.x][b.y])
18             if(b.turn<=T)
19                 return true;
20     return false;
21 }
22 bool bfs()
23 {
24     queue<node>Q;
25     Q.push(per);
26     node cur,next;
27     while(!Q.empty())
28     {
29         cur=Q.front();
30         Q.pop();
31         vis[cur.x][cur.y]=true;
32         if(cur.x==ex&&cur.y==ey&&cur.turn<=T)
33             return true;
34         if(cur.turn>T)
35             break;
36         for(int i=0;i<4;i++)
37         {
38             next.x=cur.x+rx[i];
39             next.y=cur.y+ry[i];
40             next.dir=i;
41             next.turn=cur.turn;
42             if(next.dir!=cur.dir&&cur.dir!=-1)
43                 next.turn++;
44             while(check(next))//一个方向搜到底
45             {
46                 Q.push(next);
47                 next.x+=rx[i];
48                 next.y+=ry[i];
49             }
50         }
51     }
52     return false;
53 }
54 int main()
55 {
56     int K;
57     cin>>K;
58     while(K--)
59     {
60         cin>>n>>m;
61         for(int i=1;i<=n;i++)
62         {
63             for(int j=1;j<=m;j++)
64             {
65                 cin>>a[i][j];
66             }
67         }
68         cin>>T>>per.y>>per.x>>ey>>ex;//这里注意是先列后行
69         per.turn=0;
70         per.dir=-1;
71         memset(vis,false,sizeof(vis));
72         if(bfs())cout<<"yes"<<endl;
73         else cout<<"no"<<endl;
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/Annetree/p/5663782.html