HDU-2612--Find a way---BFS广搜

来源:互联网 发布:安卓模拟器 知乎 编辑:程序博客网 时间:2024/05/21 13:55

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

题意:Y和M要在KFC见面,但是KFC有很多个,现在问在哪一个KFC见面才能使他们两个加起来的步数最短。一个单元为11步。

思路:上下左右四个搜索。这个题拿过来一看,可能就会想到枚举每一个KFC然后计算出两个人的步数,然后找出最大值。我就是这样想的,敲完之后就华丽的TLE了,然后受别人指点用两个dis数组记录出来每一个点的步数,然后最后再找KFC的点,计算最大值。

AC代码:

#include<iostream>#include<queue>#include<cstdio>#include<cstring>using namespace std;const int MAX=0x3f3f3f3f;int flag[210][210];char s[210][210];int n,m;int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};int dis1[210][210];int dis2[210][210];struct node{    int x;    int y;    int step;} nod;int bfs(int x,int y,int dis[][210]){    memset(flag,0,sizeof(flag));    memset(dis,MAX,sizeof(dis));    queue<node>q;    nod.x=x,nod.y=y,nod.step=0;    q.push(nod);    flag[x][y]=1;    while(!q.empty())    {        nod=q.front();        q.pop();        int xx=nod.x,yy=nod.y,t=nod.step;        for(int i=0; i<=3; i++)        {            int a=xx+dir[i][0],b=yy+dir[i][1];            nod.x=a,nod.y=b,nod.step=t+11;            if(a>=0&&b>=0&&a<n&&b<m&&!flag[a][b]&&s[a][b]!='#')            {                flag[a][b]=1;                q.push(nod);                dis[a][b]=nod.step;            }        }    }    return -1;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        int i,j;        for(i=0; i<=n-1; i++)            scanf("%s",s[i]);        int t1=0,t2=0,t3=0,t4=0;        int k=0;        for(i=0; i<=n-1; i++)        {            for(j=0; j<=m-1; j++)            {                if(s[i][j]=='Y')                {                    t1=i;                    t2=j;                }                if(s[i][j]=='M')                {                    t3=i;                    t4=j;                }            }        }        bfs(t1,t2,dis1);//在这里将dis数组传过去更新值        bfs(t3,t4,dis2);        int Min=MAX;        for(i=0;i<=n-1;i++)        {            for(j=0;j<=m-1;j++)            {                if(s[i][j]=='@'&&dis1[i][j]!=MAX&&dis2[i][j]!=MAX)                    Min=min(dis1[i][j]+dis2[i][j],Min);            }//当遇到@的时候并且Y和M都能到达这个@就加起来计算最大值。        }        cout<<Min<<endl;    }}

附上TLE代码:

#include<iostream>#include<queue>#include<cstdio>#include<cstring>using namespace std;int flag[210][210];char s[210][210];int n,m;int dis[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};struct node{    int x;    int y;    int step;} nod;int bfs(int x,int y,int x1,int y1){    memset(flag,0,sizeof(flag));//这里相当于用了四个循环!铁定TLE啊!    queue<node>q;    nod.x=x,nod.y=y,nod.step=0;    q.push(nod);    flag[x][y]=1;    while(!q.empty())    {        nod=q.front();        q.pop();        int xx=nod.x,yy=nod.y,t=nod.step;        if(xx==x1&&yy==y1)        {            return t;        }        for(int i=0; i<=3; i++)        {            int a=xx+dis[i][0],b=yy+dis[i][1];            nod.x=a,nod.y=b,nod.step=t+11;            if(a>=0&&b>=0&&a<n&&b<m&&!flag[a][b]&&(s[a][b]=='.'||(a==x1&&b==y1)))            {                flag[a][b]=1;                q.push(nod);            }        }    }    return -1;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        int i,j;        for(i=0; i<=n-1; i++)            scanf("%s",s[i]);        int t1=0,t2=0,t3=0,t4=0;        int sum[300][2]= {0};        for(i=0;i<=210;i++)            for(j=0;j<=1;j++)            sum[i][j]=0;        int k=0;        for(i=0; i<=n-1; i++)        {            for(j=0; j<=m-1; j++)            {                if(s[i][j]=='Y')                {                    t1=i;                    t2=j;                }                if(s[i][j]=='M')                {                    t3=i;                    t4=j;                }            }        }        for(i=0; i<=n-1; i++)        {            for(j=0; j<=m-1; j++)            {                if(s[i][j]=='@')                {                    sum[k][0]=bfs(t1,t2,i,j);                    sum[k++][1]=bfs(t3,t4,i,j);                }            }        }        int Min=0x3f3f3f3f;        for(i=0; i<=k-1; i++)        {            if(sum[i][0]!=-1&&sum[i][1]!=-1&&Min<sum[i][0]+sum[i][1])                    Min=sum[i][0]+sum[i][1];        }        printf("%d\n",Min);    }}
原创粉丝点击