HDU 2612 Find a way 题解

Find a way

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 25379    Accepted Submission(s): 8243




Problem Description
Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
 


Input
The input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’    express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
 


Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
 


Sample Input
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
 


Sample Output
66
88
66
 


Author
yifenfei
 


Source
 


Recommend
yifenfei   |   We have carefully selected several similar problems for you:   1254  1728  1072  1175  2579 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这道题因为有两个人要走
所以此处对两个人
每一个KFC
进行分别的搜索
搜索到一个KFC对应的两个值相加最小
就直接输出
但是要注意一个问题
先上我的TLE代码
  1 //Author:LanceYu
  2 #include<iostream>
  3 #include<string>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<fstream>
  7 #include<iosfwd>
  8 #include<sstream>
  9 #include<fstream>
 10 #include<cwchar>
 11 #include<iomanip>
 12 #include<ostream>
 13 #include<vector>
 14 #include<cstdlib>
 15 #include<queue>
 16 #include<set>
 17 #include<ctime>
 18 #include<algorithm>
 19 #include<complex>
 20 #include<cmath>
 21 #include<valarray>
 22 #include<bitset>
 23 #include<iterator>
 24 #define ll long long
 25 using namespace std;
 26 const double clf=1e-8;
 27 //const double e=2.718281828;
 28 const double PI=3.141592653589793;
 29 const int MMAX=2147483647;
 30 //priority_queue<int>p;
 31 //priority_queue<int,vector<int>,greater<int> >pq;
 32 struct node
 33 {
 34     int x,y,step;
 35 };
 36 queue<node> q;
 37 int n,k,vis[201][201];
 38 char map[201][201];
 39 int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};//四个方向
 40 int bfs(int a,int b,int r1,int r2)
 41 {
 42     while(!q.empty())
 43         q.pop();
 44     int i;
 45     q.push(node{a,b,0});
 46     vis[a][b]=1;
 47     while(!q.empty())
 48     {
 49         node t=q.front();
 50         q.pop();
 51         if(t.x==r1&&t.y==r2)
 52             return t.step;
 53         for(i=0;i<4;i++)
 54         {
 55             int dx=t.x+dir[i][0];
 56             int dy=t.y+dir[i][1];
 57             if(dx>=0&&dy>=0&&dx<n&&dy<k&&!vis[dx][dy]&&map[dx][dy]!='#')//正常搜索
 58             {
 59                 vis[dx][dy]=1;
 60                 q.push(node{dx,dy,t.step+1});
 61             }
 62         }
 63     }
 64     return MMAX;//如果搜不到就返回一个不能使ans改变的值
 65 }
 66 int main()
 67 {
 68     int a1,b1,a2,b2,r1[40001],r2[40001];
 69     while(scanf("%d%d",&n,&k)!=EOF)
 70     {
 71         int t=0,ans=MMAX,temp=0;
 72         for(int i=0;i<n;i++)
 73         {
 74             scanf("%s",&map[i]);
 75             for(int j=0;j<k;j++)
 76             {
 77                 if(map[i][j]=='Y')
 78                 {
 79                     a1=i;
 80                     b1=j;
 81                 }
 82                 if(map[i][j]=='M')//求出两个点的位置作为起点
 83                 {
 84                     a2=i;
 85                     b2=j;
 86                 }
 87                 if(map[i][j]=='@')//如果是KFC放到数组里面
 88                 {
 89                     r1[t]=i;
 90                     r2[t]=j;
 91                     t++;
 92                 }
 93             }
 94         }
 95         for(int i=0;i<t;i++)//寻找能到的KFC的最小值
 96         {
 97             temp=0; 
 98             memset(vis,0,sizeof(vis));
 99             temp+=bfs(a1,b1,r1[i],r2[i]);
100             memset(vis,0,sizeof(vis));
101             temp+=bfs(a2,b2,r1[i],r2[i]);
102             ans=min(ans,temp);
103         }
104         printf("%d\n",ans*11);
105     }
106     return 0;
107 }

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

乍一看这个代码似乎还很有道理

然而

但是为什么会T呢

原因其实很简单

就是因为bfs算法时间复杂度较高

如果多次进行bfs的话

铁定超时

此处一个KFC就进行一次搜索

导致超时

于是笔者想出了一个较为不错的方法

 只进行一次bfs

记录下所能到达的位置所需的步数

这样只有两次深搜即可

但是这里要注意一个小小的bug

就是KFC可能到不了

笔者因为这个WA了几次的

下面附上我精确注释

谁都能看懂的代码

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  1 //Author:LanceYu
  2 #include<iostream>
  3 #include<string>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<fstream>
  7 #include<iosfwd>
  8 #include<sstream>
  9 #include<fstream>
 10 #include<cwchar>
 11 #include<iomanip>
 12 #include<ostream>
 13 #include<vector>
 14 #include<cstdlib>
 15 #include<queue>
 16 #include<set>
 17 #include<ctime>
 18 #include<algorithm>
 19 #include<complex>
 20 #include<cmath>
 21 #include<valarray>
 22 #include<bitset>
 23 #include<iterator>
 24 #define ll long long
 25 using namespace std;
 26 const double clf=1e-8;
 27 //const double e=2.718281828;
 28 const double PI=3.141592653589793;
 29 const int MMAX=2147483647;
 30 //priority_queue<int>p;
 31 //priority_queue<int,vector<int>,greater<int> >pq;
 32 struct node
 33 {
 34     int x,y;
 35 };
 36 
 37 int n,k,vis[201][201];
 38 char map[201][201];
 39 int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};//四个方向 
 40 void bfs(int a,int b,int step[][201])//暴力枚举能到的地方各点的步数 
 41 {
 42     int i;
 43     queue<node> q;
 44     q.push(node{a,b});
 45     vis[a][b]=1;
 46     while(!q.empty())
 47     {
 48         node t=q.front();
 49         q.pop();
 50         for(i=0;i<4;i++)
 51         {
 52             int dx=t.x+dir[i][0];
 53             int dy=t.y+dir[i][1];
 54             if(dx>=0&&dy>=0&&dx<n&&dy<k&&!vis[dx][dy]&&map[dx][dy]!='#'&&!vis[dx][dy])//基本搜索 
 55             {
 56                 vis[dx][dy]=1;
 57                 step[dx][dy]=step[t.x][t.y]+1;
 58                 q.push(node{dx,dy});
 59             }
 60         }
 61     }
 62 }
 63 int main()
 64 {
 65     int a1,b1,a2,b2,step1[201][201],step2[201][201];
 66     while(scanf("%d%d",&n,&k)!=EOF)
 67     {
 68         memset(step1,0,sizeof(step1));
 69         memset(step2,0,sizeof(step2));
 70         int t=0,ans=MMAX;
 71         for(int i=0;i<n;i++)
 72         {
 73             scanf("%s",map[i]);
 74             for(int j=0;j<k;j++)
 75             {
 76                 if(map[i][j]=='Y')
 77                 {
 78                     a1=i;
 79                     b1=j;
 80                 }
 81                 if(map[i][j]=='M')//把两个点记录下来 
 82                 {
 83                     a2=i;
 84                     b2=j;
 85                 }
 86             }
 87         }
 88             memset(vis,0,sizeof(vis));
 89             bfs(a1,b1,step1);
 90             memset(vis,0,sizeof(vis));
 91             bfs(a2,b2,step2);
 92             for(int i=0;i<n;i++)//遍历所有元素,使得能走到KFC且为最小 
 93             {
 94                 for(int j=0;j<k;j++)
 95                 {
 96                     if(map[i][j]=='@'&&step1[i][j]&&step2[i][j]&&(step1[i][j]+step2[i][j]<ans))//注意此处step为0代表KFC到不了 
 97                     ans=step1[i][j]+step2[i][j]; 
 98                 }
 99             }
100             printf("%d\n",ans*11);
101     }
102     return 0;
103 }

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

此时能够AC 时间为31ms

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note:需要注意下bfs的使用次数即可

2018-11-16  00:25:12  Author:LanceYu

猜你喜欢

转载自www.cnblogs.com/lanceyu/p/9967036.html