【JAVA】PAT 乙级 1065 单身狗(测试点3、4超时)


题目链接
“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。

输入格式:
输入第一行给出一个正整数 N(≤ 50 000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤ 10 000),为参加派对的总人数;随后一行给出这 M 位客人的 ID,以空格分隔。题目保证无人重婚或脚踩两条船。

输出格式:
首先第一行输出落单客人的总人数;随后第二行按 ID 递增顺序列出落单的客人。ID 间用 1 个空格分隔,行的首尾不得有多余空格。

输入样例:

3
11111 22222
33333 44444
55555 66666
7
55555 44444 10000 88888 22222 11111 23333

输出样例:

5
10000 23333 44444 55555 88888

这道题的思路挺简单的
创建一个长度为100000的数组cp,来储存夫妻的信息

Integer[] cp = new Integer[100000];

这里用Integer而不用int是因为ID号可能等于0,如果用int的话,缺省状态下数组元素全为0,而Integer缺省状态下数组元素为null。

记录夫妻信息的时候记得是双向记录

for (int i = 0; i < N; i++) {
	in.nextToken();
	int ta = (int) in.nval;
	in.nextToken();
	int tb = (int) in.nval;
	cp[ta] = tb;
	cp[tb] = ta;
}

用一个set来储存落单的客人的信息,使用TreeSet的原因是可以自动排序

Set<Integer> party = new TreeSet<Integer>();

如果cp对应的ID元素为null,则将该ID放入set。如果该客人不是单身,则查看set里是否有他/她的另一半,没有则放入set,有的话则把他/她的另一半从set删除。

	for (int i = 0; i < M; i++) {
		in.nextToken();
		int q = (int) in.nval;
		if (cp[q] == null) {
			party.add(q);
		} else {
			if (!party.contains(cp[q])) {
				party.add(q);
			} else {
				party.remove(cp[q]);
			}
		}
	}

最后set的大小就是落单的人数
用一个foreach结构的循环输出set里的客人ID

	out.println(party.size());
	int count = 0;
	for (int tem : party) {
		if (count == 0) {
			out.printf("%05d", tem);
		} else {
			out.printf(" %05d", tem);
		}
			count++;
	}

然而JAVA又双叒叕超时了…我真的想不出还有什么更省时的办法,如果大家有想法欢迎在评论区留言讨论

完整代码(测试点3、4超时)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Set;
import java.util.TreeSet;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		StreamTokenizer in = new StreamTokenizer(bf);
		in.nextToken();
		Integer[] cp = new Integer[100000];
		int N = (int) in.nval;
		for (int i = 0; i < N; i++) {
			in.nextToken();
			int ta = (int) in.nval;
			in.nextToken();
			int tb = (int) in.nval;
			cp[ta] = tb;
			cp[tb] = ta;
		}
		in.nextToken();
		int M = (int) in.nval;
		Set<Integer> party = new TreeSet<Integer>();
		for (int i = 0; i < M; i++) {
			in.nextToken();
			int q = (int) in.nval;
			if (cp[q] == null) {
				party.add(q);
			} else {
				if (!party.contains(cp[q])) {
					party.add(q);
				} else {
					party.remove(cp[q]);
				}
			}
		}
		out.println(party.size());
		int count = 0;
		for (int tem : party) {
			if (count == 0) {
				out.printf("%05d", tem);
			} else {
				out.printf(" %05d", tem);
			}
            count++;
		}
		out.flush();
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值