【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();
}
}