此题看数据量已经达到10^5,如果双循环暴力的话O(n2)时间复杂度,肯定会有测试点超时。
因此应该想到空间换时间,此题可以开两个散列表,一个用来记录每一个编号的配偶(默认不存在未-1),另一个用来记录一个编号是否在输入的参加派对的人里出现过(默认是为false)。
首先将题中输入的n对配偶录入第一个散列表中,接着将题中输入的m个参加派对的人对应的第二个散列表的值改为true(表示出现了)。
最后输出那些单身的人(即在第一个散列表值为-1或配偶在第二个散列表的值为false)。
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int spouse[100010];
bool cunzai[100010] = {false};
void init(){
for(int i=0; i<=100010; i++){
spouse[i] = -1;
}
}
int main(){
init();
int n;
scanf("%d", &n);
for(int i=0; i<n; i++){
int a, b;
scanf("%d %d", &a, &b);
spouse[a] = b;
spouse[b] = a;
}
scanf("%d", &n);
int arr[n];
int num = 0;
for(int i=0; i<n; i++){
int bh;
scanf("%d", &bh);
cunzai[bh] = true;
arr[num++] = bh;
}
int res[n];
int r_num = 0;
for(int i=0; i<num; i++){
if(spouse[arr[i]]==-1 || !cunzai[spouse[arr[i]]]){
res[r_num++] = arr[i];
}
}
sort(res, res+r_num);
printf("%d\n", r_num);
for(int i=0; i<r_num; i++){
printf("%05d", res[i]);
if(i != r_num-1) printf(" ");
}
return 0;
}