PAT 乙级 1065 单身狗

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a845717607/article/details/86308403

1065 单身狗 (25 point(s))

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

输入格式:

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

经验总结: 

emmmmmm   原来做过类似的,所以做这题感觉就不是怎么难了,但是通过率0.23肯定还是有原因的,我猜应该是思路问题。

首先,这题很明显,要用hash来解决,具体的话使用一维数组或者map都可以,我就选择最基本的数组实现的,虽然占用的空间确实大了一点....但是速度还可以。
其次,需要开两个数组,一个(设为A)用来存储所有人的另一半,没有另一半的这里我用的-1(因为00000也是一个人的ID),另一个(设为B)存储这个人的另一半是否到场(当然这里仅对于有另一半的人)
再者,面对输入的人ID,先访问A[ ID ],如果等于-1,直接确定是单身狗,不等于的话,就将B[ A[ ID ] ]置为1,表明ID的另一半的另一半(就是ID)已经到场了,这里可能有点绕,但是理解了之后就会发现很简单了,然后把他放入待定(因为不知道他的另一半是否来了)
最后,依次访问所有的待定的人(设为ID),如果B[ ID ]等于1,就说明他的另一半来了,说明他不是单身狗,反之则是单身狗,然后将其放入单身狗的容器中( ̄▽ ̄") ,最后再进行排序输出就行啦~~

怎么样,串一下思路是不是觉得也不是很难吧~(•‾̑⌣‾̑•)✧˖°

AC代码

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=1000010;
int p[maxn];
bool attend[maxn];
int main()
{
	int n,a,b,t,m;
	vector<int> ans,temp;
	while(~scanf("%d",&n))
	{
		fill(p,p+maxn,-1);
		memset(attend,0,sizeof(attend));
		for(int i=0;i<n;++i)
		{
			scanf("%d %d",&a,&b);
			p[a]=b;
			p[b]=a;
		}
		scanf("%d",&m);
		for(int i=0;i<m;++i)
		{
			scanf("%d",&t);
			if(p[t]==-1)
				ans.push_back(t);
			else
			{
				attend[p[t]]=1;
				temp.push_back(t);
			}
		}
		for(int i=0;i<temp.size();++i)
		{
			if(attend[temp[i]]==0)
				ans.push_back(temp[i]);
		}
		sort(ans.begin(),ans.end());
		printf("%d\n",ans.size());
		for(int i=0;i<ans.size();++i)
		{
			printf("%05d",ans[i]);
			if(i!=ans.size()-1)
				printf(" ");
			else
				printf("\n");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a845717607/article/details/86308403