题目:
“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。
输入格式:
输入第一行给出一个正整数 N(≤50000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤10000),为参加派对的总人数;随后一行给出这 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
错误代码(超时):
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
vector<pair<int,int>> v(n);
for(int i=0;i<n;i++){
int x,y;
scanf("%d %d",&x,&y);
v[i]={x,y};
}
int m,ans;
scanf("%d",&m);
ans=m;
vector<int> res(m);
for(int i=0;i<m;i++){
cin >> res[i];
}
sort(res.begin(),res.end());
for(int i=0;i<n;i++){
int x=v[i].first;
int y=v[i].second;
int cnt=0;
int xx=-1,yy=-1;
for(int j=0;j<m;j++){
if(x<res[j]&&xx==-1){
break;
}
if(y<res[j]&&yy==-1){
break;
}
if(res[j]==x){
xx=j;
cnt++;
}
if(res[j]==y){
yy=j;
cnt++;
}
if(cnt==2){
break;
}
}
if(cnt==2){
ans-=2;
res[xx]=0;
res[yy]=0;
}
}
cout << ans << '\n';
int ct=0;
for(int i=0;i<m;i++){
if(res[i]!=0){
if(ct==0){
printf("%d",res[i]);
}else{
printf(" %d",res[i]);
}
ct++;
}
}
return 0;
}
思考:
我使用pair数组v存储每队的情侣ID,使用int数组res存储客人的ID代码,按ID升序排列res数组,然后使用两个for去找res数组是否存在一整队情侣,如果存在,则把对应客人的ID改成0,数量-2,输出ID不为0的客人ID,因为使用两个for,所以数据量大的时候超时了,剃了,过不了,所以这题关键在于如何缩小时间复杂度,那么如何解决呢?(最好是一个for就能解决)
解决:
因为情侣是一对的,只有情侣中的一个是不完整的,好像可以使用map<string,string>,情侣的一方是另一个人的映射,因为客人ID的输出是要升序的,而且需要查找,所以可以使用set<string>,使用for的加强遍历set容器来查找情侣,如果没有找到的话加入新的set中,输出新set的元素即可
正确代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
map<string,string> mp;
for(int i=0;i<n;i++){
string x,y;
cin >> x >> y;
mp[x]=y;
mp[y]=x;
}
int m;
cin >> m;
set<string> s;
for(int i=0;i<m;i++){
string x;
cin >> x;
s.insert(x);
}
set<string> ans;
for(auto t:s){
if(s.find(mp[t])==s.end()){
ans.insert(t);
}
}
int cnt=0;
cout << ans.size() << '\n';
for(auto t:ans){
if(cnt==0){
cout << t;
}else{
cout << ' ' << t;
}
cnt++;
}
return 0;
}
学到的知识:
set:
1.遍历一般是使用for的加强遍历,因为其无法通过下标访问。
2.其count和find函数与map是一样的,count返回键的个数,find找不到返回end()。
3.set添加元素使用insert。