暑假集训第一周上 D Find a way双向搜索

暑假集训第一周上 D Find a way

双向搜索
题目:
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.
输入:
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
输出:
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.
样例:
输入:
4 4
Y.#@

.#…
@…M
4 4
Y.#@

.#…
@#.M
5 5
Y…@.
.#…
.#…
@…M.
#…#
输出:
66
88
66
—————————————————————————————————————————
题意:
两个人在地图上的两个位置上,两个人想要见面,所以约在两人路程最近的那个汉堡店见面,请你求出符合上述条件的汉堡店是哪一个。Y,M分别代表两个人;#代表路障;“.”代表道路;@代表汉堡店。
思路:
对两个人分别进行bfs,用sum1和sum2数组分别记录两人到各个汉堡店的距离;最后通过for循环找出两个sum加和后路程最短的那个汉堡店。
————————————————————————————————————————
代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define maxx 0x7fffffff
using namespace std;
int n,m;
char e[210][210];
int book1[210][210];
int book2[210][210];
int sum1[210][210];
int sum2[210][210];
int b[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct ppp
{
    int x,y;
}f,g;
queue<ppp>q;
void bfs1(int x,int y)//没有啥判断条件,把地图遍历完就行
{
    int i,j,xx,yy;
    while(!q.empty())
    {
        q.pop();
    }
    f.x=x;f.y=y;
    q.push(f);
    book1[x][y]=1;
    sum1[x][y]=0;
    while(!q.empty())
    {
    	f=q.front();
    	q.pop();
        for(i=0;i<4;i++)
        {
            xx=f.x+b[i][0];
            yy=f.y+b[i][1];
            if(xx>=0&&xx<n&&yy>=0&&yy<m)
            {
            	if(e[xx][yy]!='#'&&book1[xx][yy]==0)
            	{
            		g.x=xx;
					g.y=yy;
            		sum1[xx][yy]=sum1[f.x][f.y]+1;
            		book1[xx][yy]=1;
					q.push(g);
				}
			}
        }
    }
}
void bfs2(int x,int y)//没有啥判断条件,把地图遍历完就行
{
    int i,j,xx,yy;
    while(!q.empty())
    {
        q.pop();
    }
    f.x=x;f.y=y;
    q.push(f);
    book2[x][y]=1;
    sum2[x][y]=0;
    while(!q.empty())
    {
    	f=q.front();
    	q.pop();
        for(i=0;i<4;i++)
        {
            xx=f.x+b[i][0];
            yy=f.y+b[i][1];
            if(xx>=0&&xx<n&&yy>=0&&yy<m)
            {
            	if(e[xx][yy]!='#'&&book2[xx][yy]==0)
            	{
            		g.x=xx;
					g.y=yy;
            		sum2[xx][yy]=sum2[f.x][f.y]+1;
            		book2[xx][yy]=1;
					q.push(g);
				}
			}
        }
    }
}
int main()
{
    int i,j,x1,y1,x2,y2,minn;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=0;i<n;i++)
        {
            scanf("%s",e[i]);
            for(j=0;j<m;j++)//找出两个人的坐标
            {
                if(e[i][j]=='Y')
                {
                    x1=i;
                    y1=j;
                }
                if(e[i][j]=='M')
                {
                    x2=i;
                    y2=j;
                }
            }
        }
        //printf("%d %d %d %d\n",x1,y1,x2,y2);
        memset(book1,0,sizeof(book1));
     	memset(sum1,0,sizeof(sum1));
        bfs1(x1,y1);//对第一个人进行bfs
		memset(book2,0,sizeof(book2));
     	memset(sum2,0,sizeof(sum2));
		bfs2(x2,y2);//对第二个人进行bfs
		minn=maxx;
		for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                //通过加和找最小
                if(e[i][j]=='@'&&book1[i][j]==1&&book2[i][j]==1)
                	if(minn>sum1[i][j]+sum2[i][j])
                    	minn=sum1[i][j]+sum2[i][j];
            }
        }
		printf("%d\n",minn*11);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值