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

这题的意思就是两个人从两个不同的地点去一个肯德基见面,但是肯德基有很多个,要找出两个人花费时间最少的那一个,并输出这个时间,走一步用11min。

建立一个数组记录到各个点的时间是多少,最后遍历一遍,找出这个地方是肯德基并且花费时间最少的。

C++代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=205;
const int INF=0x7fffffff;
char ch[maxn][maxn];
int vis[maxn][maxn];
int step[maxn][maxn];
int n,m;
int dis[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct node
{
    int x,y,tim;
};
void bfs(int a,int b)
{
    queue<node>q;
    node s,e;
    s.x=a;
    s.y=b;
    s.tim=0;
    vis[s.x][s.y]=1;
    q.push(s);
    while(!q.empty())
    {
        s=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            e.x=s.x+dis[i][0];
            e.y=s.y+dis[i][1];
            if(ch[e.x][e.y]=='#'||e.x<0||e.y<0||e.x>=n||e.y>=m||vis[e.x][e.y])
                continue;
            e.tim=s.tim+1;
            step[e.x][e.y]+=e.tim;
            vis[e.x][e.y]=1;
            q.push(e);
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int minn=INF;
        memset(ch,0,sizeof(ch));
        memset(step,0,sizeof(step));
        for(int i=0;i<n;i++)
            scanf("%s",ch[i]);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
        {
            if(ch[i][j]=='Y'||ch[i][j]=='M')
            {
                memset(vis,0,sizeof(vis));
                bfs(i,j);
            }
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
        {
            if(ch[i][j]=='@'&&step[i][j]!=0)
                minn=min(minn,step[i][j]);
        }
        printf("%d\n",minn*11);
    }
    return 0;
}

Java代码:

版本1 分别用step数组表示Y和M到@的距离,最后相加再比较,step为三维数组。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.math.*;
public class Main {
	final static int maxn=205;
	final static int INF=0x7fffffff;
	public static int n,m;
	public static int [][]dis={{0,1},{0,-1},{1,0},{-1,0}};
	public static boolean[][] vis=new boolean [maxn][maxn];
	public static int [][][]step=new int [2][maxn][maxn];
	public static char [][]ch=new char [maxn][maxn];
	public static class node
	{
		int x,y;
		node()
		{
		}
		node(int x,int y)
		{
			this.x=x;
			this.y=y;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin =new Scanner(System.in);
		while(cin.hasNext())
		{
			for(int i = 0; i < 2; i++)
				for(int j = 0; j < maxn; j++)
					for(int k = 0; k < maxn; k++)
						step[i][j][k] = 0;
			int minn=INF;
			n=cin.nextInt();
			m=cin.nextInt();
			for(int i=0;i<n;i++)
			{
				ch[i]=cin.next().toCharArray();	
			}
			Queue<node>q =new LinkedList<>();		
			

			
			
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
				{
					if(ch[i][j]=='Y'||ch[i][j]=='M')
					{
						for(int k=0;k<n;k++)
							for(int d=0;d<m;d++)
								vis[k][d]=false;
						bfs(i,j, ch[i][j] == 'Y' ? 0 : 1);
					}
				}
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
				{
					if(ch[i][j]=='@'&&step[0][i][j]!=0&&step[1][i][j] != 0)
						minn=Math.min(step[0][i][j] + step[1][i][j], minn);
				}
			System.out.println(minn);
			}
			
		}
	private static void bfs(int x, int y, int cnt) {
		// TODO Auto-generated method stub
		Queue<node>q =new LinkedList<>();
		vis[x][y]=true;
//		step[cnt][x][y] = 0;
		q.add(new node(x, y));
		while(!q.isEmpty())
		{
			node s=q.peek();
			q.poll();
			//System.out.println(s.x + "  " + s.y);
			for(int i=0;i<4;i++)
			{
				node e = new node();
				e.x=s.x+dis[i][0];
				e.y=s.y+dis[i][1];
				if(e.x<0||e.y<0||e.x>=n||e.y>=m || ch[e.x][e.y] == '#' || vis[e.x][e.y]) continue;
				step[cnt][e.x][e.y] = step[cnt][s.x][s.y] + 11;
				vis[e.x][e.y]=true;
				q.add(e);
			}
		}
	}
}

 版本2 step数组直接表示Y和M到达@的总时间,step为二维数组。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.math.*;

public class Main {
	final static int maxn=205;
	final static int INF=0x7fffffff;
	public static int n,m;
	public static int [][]dis={{0,1},{0,-1},{1,0},{-1,0}};
	public static boolean[][] vis=new boolean [maxn][maxn];
	public static int [][]step=new int [maxn][maxn];
	public static char [][]ch=new char [maxn][maxn];
	public static class node
	{
		int x,y,tim;
		node()
		{
		}
		node(int x,int y,int tim)
		{
			this.x=x;
			this.y=y;
			this.tim=tim;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin =new Scanner(System.in);
		while(cin.hasNext())
		{
			
				for(int j = 0; j < maxn; j++)
					for(int k = 0; k < maxn; k++)
						step[j][k] = 0;
			int minn=INF;
			n=cin.nextInt();
			m=cin.nextInt();
			for(int i=0;i<n;i++)
			{
				ch[i]=cin.next().toCharArray();	
			}
			Queue<node>q =new LinkedList<>();		
			

			
			
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
				{
					if(ch[i][j]=='Y'||ch[i][j]=='M')
					{
						for(int k=0;k<n;k++)
							for(int d=0;d<m;d++)
								vis[k][d]=false;
						bfs(i,j);
					}
				}
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
				{
					if(ch[i][j]=='@'&&step[i][j]!=0)
						minn=Math.min(step[i][j], minn);
				}
			System.out.println(minn*11);
			}
			
		}
	private static void bfs(int x, int y) {
		// TODO Auto-generated method stub
		Queue<node>q =new LinkedList<>();
		vis[x][y]=true;
		
		q.add(new node(x, y,0));
		while(!q.isEmpty())
		{
			node s=q.peek();
			q.poll();
			//System.out.println(s.x + "  " + s.y);
			for(int i=0;i<4;i++)
			{
				node e = new node();
				e.x=s.x+dis[i][0];
				e.y=s.y+dis[i][1];
				if(e.x<0||e.y<0||e.x>=n||e.y>=m || ch[e.x][e.y] == '#' || vis[e.x][e.y]) continue;
				e.tim=s.tim+1;
				step[e.x][e.y] += e.tim;
				vis[e.x][e.y]=true;
				q.add(e);
			}
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值