我们接着上文说
四、pair
1. 声明
template pair<class T1, class T2> templatename;
templatename name;
pair<class T1, class T2> 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 <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <algorithm>
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 <class > 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 <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
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;
}
请您留下您的评价
虽然没什么用
- 好
- 差
嘻嘻嘻