「题解」「STL」上网统计、有序表的最小和、桐桐的新闻系统、 查字典、Let the Balloon Rise、题海战之二

我们接着上文

四、pair

1. 声明

template pair templatename;
templatename name;

pair name;

2.函数

make_pair(x, y);
制作一个pair容器
p.first;
返回第一个元素
p.second;
返回第二个元素

3. 应用之Let the Balloon Rise

题目描述

在ACM比赛中,你每解决一道题,你就可以获得一个气球,不同颜色的气球代表你解决了不同的问题。在GM同学参加的一场ACM比赛中,他发现场面上有N个气球,并熟练的说出了气球的颜色。

请你编写一个程序,找出气球数量最多的颜色。

输入格式

有多组样例输入。

每组样例第一行输入一个整数N (0 < N <= 1000) ,代表一共有N个气球。若N=0,则代表输入结束。

接下来N行每行输入一个不多于15个字母的字符串代表颜色。

输出格式

对于每组样例数据,在单独的一行内输出数量最多的那种颜色的气球。(数据保证输出是唯一的)

样例

 样例输入

5
green
red
blue
red
red
3
pink
orange
pink
0

 样例输出

red
pink
分析

这道题大多数人用了map做,这里我们抛砖引玉一下,用这道题讲解一下pair应用,这里我们不过多描述,看代码在线描述

代码
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int M = 1e4 + 5;
typedef pair<string, int> balloon;
balloon a[M];

bool cmp(balloon x, balloon y) {
	return x.second > y.second;
}

void run(int n) {
	for(int i = 1; i <= n; i ++) {//初始化
		a[i].first = a[i].second = 0;
	}
	int l = 0;
	for(int i = 1; i <= n; i ++) {
		string color;
		cin >> color;
		bool flag = true;//用于判断此前是否存在这种颜色的气球
		for(int j = 1; j <= l; j ++) {
			if(a[j].first == color) {
				flag = false;//找到这种颜色的气球
				++ a[j].second;
				break;
			}
		}
		if(flag) {
			++ l;//新建一个pair储存
			a[l].first = color;
			a[l].second = 1;
		}
	}
	sort(a + 1, a + 1 + l, cmp);//排序求最大
	cout << a[1].first << endl;
}

int main() {
	int t;
	scanf("%d", &t);
	while(t != 0) {//多组数据
		run(t);
		scanf("%d", &t);
	}
	return 0;
}

五、set

1. 声明

set  name

2. 函数

se.insert(x);
添加一个元素x
se.insert(k, x);
在k处添加元素x,自动排序
s.erase(5);
删除一个元素x
s.erase(l, r);
删除[l, r]之间的元素
s.clear();
清空s中的所有元素
s.begin();
返回第一个元素的迭代器
s.end();
返回最后一个元素的下一个位置的迭代器
s.size();
set的大小
s.empty();
判断s是否为空
s.count(x);
查找元素x的个数
s.find(x);
如果存在x,返回x所对应的迭代器,否则返回s.end()
s.upper_bound(x);
返回第一个元素大于x的迭代器
s.lower_bound(x);
返回最后一个元素小于x的迭代器

3. 应用之题海战

题目描述

 某信息学奥赛教练经验丰富,他的内部题库有 m 道题。他有 n 个学生,第 i 个学生已经做过p[i]道题。由于马上要进行noip考试,该教练准备举行 k 场比赛和训练。每场比赛或训练都会有一些他的学生参加,但是如何选题令他非常烦恼。对于每场比赛,他要保证所出的题没有任何一道已有任何一个学生做过;而对于每场训练,他要保证所出的所有题都被每一个参赛学生做过。

输入格式

 第1行2个正整数n和m,表示学生数和题库中的题目总量。
 第2~n+1行,先是1个正整数p,然后p个整数表示第i个学生的做题记录(可以重复做同一道题)。
 第n+2行,1个正整数k,表示要举行比赛和训练的总场数(可能有学生重复报名)。
 接下来的k行,每行的第1个整数type表示是训练或者比赛(1为训练,0为比赛)。第二个数q表示参赛学生数,然后q个正整数表示参赛学生编号。每一行的两个数之间有一个空格。

输出格式

 共k行,每行表示本次训练或比赛可选的最多题目(由小到大排序,中间用一个空格隔开,如果没有输出一个空行)。

样例

样例输入

5 10
2 3 7
1 3
2 4 7
3 3 6 10
7 1 2 3 4 7 8 9
6
0 3 3 4 5
0 3 1 3 4
1 2 1 3
0 1 5
1 1 2
1 2 3 5

样例输出

5
1 2 5 8 9
7
5 6 10
3
4 7

数据范围与提示

1 ≤ n,k ≤ 100
1 ≤ m ≤ 10000

代码
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int M = 1e2 + 5;
set <int> a[M], all;

int main() {
	int n, m;
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i ++) {
		a[i].clear();
		int num;
		scanf("%d", &num);
		for(int j = 1; j <= num; j ++) {
			int x;
			scanf("%d", &x);
			a[i].insert(x);
		}
	}
	for(int i = 1; i <= m; i ++) {
		all.insert(i);
	}
	int t;
	scanf("%d", &t);
	for(; t > 0; t --) {
		int choice, num;
		scanf("%d %d", &choice, &num);
		set<int> ans = all;
		if(choice == 1) {
			for(; num > 0; num --) {
				int x;
				scanf("%d", &x);
				for(set<int>::iterator it = ans.begin(); it != ans.end();) {
					if(a[x].find(*it) == a[x].end()) {
						ans.erase(it ++);
					}
					else {
						it ++;
					}
				}
			}
		}
		else {
			for(; num > 0; num --) {
				int x;
				scanf("%d", &x);
				for(set<int>::iterator it = ans.begin(); it != ans.end();) {
					if(a[x].find(*it) != a[x].end()) {
						ans.erase(it ++);
					}
					else {
						it ++;
					}
				}
			}
		}
		for(set<int>::iterator it = ans.begin(); it != ans.end(); ++ it) {
			cout << (*it) << " ";
		}
		puts("");
	}
	return 0;
}

请您留下您的评价虽然没什么用


  • 嘻嘻嘻

你可能感兴趣的:(STL,数据结构,c++,stl)