PAT 乙级练习 1065 单身狗 - 超级详细的思路讲解

PAT 乙级练习 题解合集

本题链接

题目

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

输入格式:
输入第一行给出一个正整数 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

思路

1. 处理输入

  1. map married;
    用来存储伴侣之间的映射。注意所有映射是双向的(便于查询),例如对于输入11111 22222,表示1111122222是夫妻,那么married[11111] = 22222;married[22222] = 11111;
  2. set guests;
    用来存储所有参加派对客人的 ID;

2. 找出单身狗

  1. set singles;
    用来存放所有单身狗的 ID,自带排序;
  2. 主要思路是不断地从guests中删去已经辨识过的 ID,并将单身狗的 ID 丢进singles,直到guests空为止
  3. 只要guests非空,就来处理guests的第一个 ID,在married中查找这个人有没有另一半:
    a. 如果这个人没有另一半,直接将其丢进singles,并在guests中删去这个人的 ID;
    b. 如果这个人有另一半,把guests中这一对的 ID 都删掉。

3. 输出答案

singles.size()即为单身狗人数,singles中所有数据即为排好序的单身狗 ID。


吐槽:看到这个题目描述就感觉是陈越姥姥写的…一看作者果然是…

代码

#include 
#include 
#include 
using namespace std;
int main() {
	int n, m, a, b;
	map<int, int> married;
	set<int> guests, singles;
	scanf("%d", &n);
	while (n--) {
		scanf("%d %d", &a, &b);
		married[a] = b;
		married[b] = a;
	} 
	scanf("%d", &m);
	while (m--) {
		scanf("%d", &a);
		guests.insert(a);
	}
	while (!guests.empty()) {
		int guy = *(guests.begin());
		if (married.count(guy) && guests.find(married[guy]) != guests.end())
			guests.erase(married[guy]);
		else
			singles.insert(guy);
		guests.erase(guy); 
	}
	printf("%d\n", singles.size());
	for (auto it = singles.begin(); it != singles.end(); ++it)
		printf("%s%05d", it == singles.begin() ? "" : " ", *it); 
	return 0;
} 

你可能感兴趣的:(PAT,乙级)