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

说明:

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

题目列表:

ZISUOJ 2022年算法基础公选课练习三(Set)_第1张图片

问题 A: {A} + {B}

ZISUOJ 2022年算法基础公选课练习三(Set)_第2张图片

思路:

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

参考题解:

#include 
using namespace std;
//using ll = long long;
//using PII = pair;
//const int N = 1e4+5;
set 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::iterator i = s.begin();i!=s.end();i++) cout << *i << ' ';
        for(auto it:s) cout << it << ' ';
		cout << '\n';
	}
	return 0;
}

问题 B: 人见人爱A-B

ZISUOJ 2022年算法基础公选课练习三(Set)_第3张图片

思路:

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

参考题解:

#include 
using namespace std;
//using ll = long long;
//using PII = pair;
//const int N = 1e4+5;
set s1,s2;
set 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 >(ans,ans.begin()));
		if(ans.size()){
			for(auto i:ans) cout << i << ' ';
			cout << '\n';
		}else cout << "NULL" << '\n';
	}
	return 0;
}

问题 C: 单词数

ZISUOJ 2022年算法基础公选课练习三(Set)_第4张图片

思路:

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

参考题解:

#include 
using namespace std;
//using ll = long long;
//using PII = pair;
//const int N = 1e4+5;
set 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: 产生冠军 

ZISUOJ 2022年算法基础公选课练习三(Set)_第5张图片

思路:

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

参考题解:

#include 
using namespace std;
//using ll = long long;
//using PII = pair;
const int N = 2e3+5;
set 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;
}

你可能感兴趣的:(算法,数据结构,c++,c语言)