Pta:单身狗

题目:

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

输入格式:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值