L2-044 大众情人 - java

题目解析

给定n个人
性别 以及 每个人对k个人的距离感

求出女生和男生异性缘最好的人

解题思路

先读题

一个人的异性缘不是由最喜欢他/她的那个异性决定的,而是由对他/她最无感的那个异性决定的

=1maxjS(i){Dij}异性缘 = \frac{1}{max_{j \in S(i) \{ D_{ij} \} }}

也就是 i 到 j 的感觉距离中取最大值 组成 S(i)

  • 然后再在 S(i) 中 取最小值
  • 这样得到的值就会使最小的 也就是异性缘最好的

所以直接找男生女生中的最小感觉距离即可


为什么是最短路中呢?
因为题目中的

  • 如果小绿本来也认识小红,或者他通过其他人也能认识小红,但通过不同渠道推导出来的距离感不一样,该怎么算呢?我们在这里做个简单定义,就将小绿对小红的距离感定义为所有推导出来的距离感的最小值。

所以得知是最短路

如何求每个人到另一个人的感觉距离呢?
floyd


先求出每个人之间的感觉距离

然后再找出异性间的感觉距离 求出最远感觉距离得到数组S

然后找女生男生的最小值即可

然后再输出

代码

import java.io.*;
import java.math.*;
import java.util.*;

public class Main
{
	static int inf = 0x3f3f3f3f;

	public static void main(String[] args) throws IOException
	{
		int n = Integer.valueOf(sc.readLine());

//		存储每个人对另一个人的感觉距离
		long map[][] = new long[n + 10][n + 10];
		for (int i = 1; i <= n; i++)
		{
			Arrays.fill(map[i], inf);
			map[i][i] = 0;
		}

//		存储是否为女生
		boolean sex[] = new boolean[n + 10];
		for (int a = 1; a <= n; a++)
		{
			String str[] = sc.readLine().split(" ");
			sex[a] = str[0].equals("F");

			int k = Integer.valueOf(str[1]);
			for (int i = 1; i <= k; i++)
			{
				String s[] = str[i + 1].split(":");
				int b = Integer.valueOf(s[0]), c = Integer.valueOf(s[1]);

//				当前 a 到 b 的感觉距离为 c 
				map[a][b] = c;
			}
		}

//		floyd 求每个人到另一个人的感觉距离
//		中间的踏板
//		也就是 i -> k -> j
		for (int k = 1; k <= n; k++)
		{
			for (int i = 1; i <= n; i++)
			{
				for (int j = 1; j <= n; j++)
				{
//					距离更小就替换
					if (map[i][j] > map[i][k] + map[k][j])
						map[i][j] = map[i][k] + map[k][j];
				}
			}
		}

//		S[i] 表示对第i个人的感觉距离最远的距离
		long S[] = new long[n + 10];

		long minF = inf, minM = inf;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
//				要为异性
				if (sex[i] != sex[j])
//					寻找最大的感觉距离
					S[i] = Math.max(S[i], map[j][i]);
			}
			if (sex[i])
				minF = Math.min(minF, S[i]);
			else
				minM = Math.min(minM, S[i]);
		}

//		输出异性缘最大的女生的
		int pos = 0;
		for (int i = 1; i <= n; i++)
		{
			if (sex[i] && minF == S[i])
			{
				if (pos++ > 0)
					out.print(" ");
				out.print(i);
			}
		}
		out.println();

//		输出异性缘最大的男生
		pos = 0;
		for (int i = 1; i <= n; i++)
		{
			if (!sex[i] && minM == S[i])
			{
				if (pos++ > 0)
					out.print(" ");
				out.print(i);
			}
		}

		out.flush();
		out.close();
	}

	static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(System.out);
}

fill
fill

split

equals

floyd
floyd
floyd


团体程序设计天梯赛-练习集-java

赞赏