ZISUOJ 2022年算法基础公选课练习三(Set)

文章分享了作者自编的C++代码,涉及集合去重、合并、差集和冠军产生的数据结构问题,通过实例展示了如何使用set进行操作,并欢迎读者提出改进建议。
摘要由CSDN通过智能技术生成

说明:

        博主为了提早预习数据结构和C++的一些知识,自己琢磨外加查阅资料所写的代码,题目来源于22年初的学院老师组织的算法基础公选课的练习。我的代码甚至思路肯定存在许多不足和错误,欢迎大家批评指正。

题目列表:

问题 A: {A} + {B}

思路:

        把两个集合的数据都放在一个集合里即可,由于集合的性质,集合会自动去重并且升序排列。注意有多组数据。

参考题解:

#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
set<int> s; 
int main(){
	//问题 A: {A} + {B}
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m;
	while(cin >> n >> m){
		s.clear();
		int temp;
		for(int i = 1;i<=n;i++){
			cin >> temp;
			s.insert(temp);
		}
		for(int i = 1;i<=m;i++){
			cin >> temp;
			s.insert(temp);
		}
//		for(set<int>::iterator i = s.begin();i!=s.end();i++) cout << *i << ' ';
        for(auto it:s) cout << it << ' ';
		cout << '\n';
	}
	return 0;
}

问题 B: 人见人爱A-B

思路:

        使用集合做差即可。注意要背下来这个集合作差的模板。

参考题解:

#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
set<int> s1,s2;
set<int> ans;
int main(){
	//问题 B: 人见人爱A-B
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m;
	while(cin >> n >> m){
		s1.clear(),s2.clear(),ans.clear();
		if(n==0&&m==0) break;
		int temp;
		for(int i = 1;i<=n;i++){
			cin >> temp;s1.insert(temp);
		}
		for(int i = 1;i<=m;i++){
			cin >> temp;s2.insert(temp);
		}
		set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),insert_iterator<set<int> >(ans,ans.begin()));
		if(ans.size()){
			for(auto i:ans) cout << i << ' ';
			cout << '\n';
		}else cout << "NULL" << '\n';
	}
	return 0;
}

问题 C: 单词数

思路:

        读入string,放入set<string>中来进行去重,然后通过查询set的size来得到答案

参考题解:

#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
set<string> s;
int main(){
	//问题 C: 单词数
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	string temp;
	while(cin >> temp){
		if(temp=="#") break;
		s.insert(temp);
	}
	cout << s.size() << '\n';
	return 0;
}

问题 D: 产生冠军 

思路:

        根据题意,我们知道战胜的人才有作为冠军候选人的机会,并且被打败的人没有做冠军候选人的机会,因此,我们只需要先用循环遍历把胜利者放入set,然后再次循环遍历删除掉set中的失败者。如果集合中的元素个数有且为1,则说明能产生冠军,否则说明不能产生冠军。

参考题解:

#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//using PII = pair<int,int>;
const int N = 2e3+5;
set<string> ans;
string player1[N],player2[N];
int main(){
	//问题 D: 产生冠军
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	while(cin >> n){
		ans.clear();//清空set 
		if(n==0) break;
		for(int i = 1;i<=n;i++){
			cin >> player1[i] >> player2[i];
			ans.insert(player1[i]);//胜利者放入冠军候选人名单
		}
		//战败者不能作为冠军候选人,即从冠军候选人名单中删去 
		for(int i = 1;i<=n;i++) ans.erase(player2[i]);
		//如果冠军候选人名单有且只有一个人,则表示能角逐出冠军 
		if(ans.size()==1) cout << "Yes\n";
		else cout << "No\n";
	}
	return 0;
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Beau_Will

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值