1. 程式人生 > >HDU 2612 Find a way 題解

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
[email protected]
.#... .#... @..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