Description
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N <= 100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
Input
输入数据有多组
每组有2行,第1行为1个正整数,表示所生成的随机数的个数:N
第2行有N个用空格隔开的正整数,为所产生的随机数。
Output
每组输出也是2行,第1行为1个正整数M,表示不相同的随机数的个数。第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
Sample Input
10
20 40 32 67 40 20 89 300 400 15
Sample Output
8
15 20 32 40 67 89 300 400
#include
using namespace std;
int main()
{
set<int>num;
int n,m,x,f;
while(cin>>n){
num.clear();
for(int i=1;i<=n;i++){
cin>>x;
num.insert(x);
}
cout<<num.size()<<endl;
set<int>::iterator it;
for(it=num.begin();it!=num.end();++it){
if(it==num.begin())
cout<<*it;
else cout<<" "<<*it;
}
printf("\n");
}
return 0;
}
Description
现有n个正整数,n≤10000,要求出这n个正整数中的第k个最小整数(相同大小的整数只计算一次),k≤1000,正整数均小于30000。
Input
第一行为n和k; 第二行开始为n个正整数的值,整数间用空格隔开。
Output
第k个最小整数的值;若无解,则输出“NO RESULT”。
Sample Input
10 3
1 3 3 7 2 5 1 2 4 6
Sample Output
3
#include
using namespace std;
int main()
{
set<int>a;
int n,k,x,f,cnt=0;
cin>>n>>k;
while(n--){
cin>>x;
a.insert(x);
}
if(k>a.size()) cout<<"NO RESULT"<<endl;
else {
set<int>::iterator it;
for(it=a.begin();it!=a.end();++it){
cnt++;
if(cnt==k) cout<<*it<<endl;
}
}
return 0;
}
Description
要英语考试,小雅同学准备考小熊同学英语单词。
会就输出YES
不会就输出NO
Input
输入一个n,(1<=n<=1000)代表要考的单词的个数;
然后每行是一个数字和这个单词;数字为0或1;
0表示记忆单词;
1表示询问单词会还是不会?
Output
对于每个单词的询问,输出YES 或NO
Sample Input
5
0 good
0 red
1 goose
0 goose
1 goose
Sample Output
NO
YES
#include
using namespace std;
int main()
{
set<string>a;
int n,f;
string x;
cin>>n;
while(n--){
cin>>f>>x;
if(f==0) a.insert(x);
else{
if(a.count(x)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
return 0;
}
Description
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有 N 条平行的轨道,如图 10.6-1 所示。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有 9趟列车,在入口处按照 {8,4,2,5,3,9,1,6,7} 的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
Input
第 1 行给出 1 个正整数 N,2≤N≤1e5 。
第 2 行给出从 1~N 的正整数序号的一个重排列,数字间以一个空格分隔
Output
输出一行一个数,表示可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
Sample Input
9
8 4 2 5 3 9 1 6 7
Sample Output
4
Tips
在纸上模拟一下入轨过程,发现每次入轨的车都会跟在第一个大于它的车的后面,如果现有轨道的最后一列车都小于他,则增加轨道
所以说,现有轨道的最后一列车以外的车号都是用不上的,可以入一辆车删一辆车,增加轨道时则不用删
用upper_bound会方便许多
#include
using namespace std;
set<int>s;
set<int>::iterator it;
int n,x,ans=1;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;//列车准备入轨
if(s.empty())s.insert(x);
else{
it=s.upper_bound(x);
if(it==s.end()){//如果x比set中任何一个数都大,增加轨数
s.insert(x);
ans++;
}
else{
s.erase(*it);//*it是第一个大于x的车号
s.insert(x);//将x放入刚刚好的位置
}
}
}
cout<<ans<<endl;
return 0;
}
Description
给出两个数集,它们的相似程度定义为Nc/Nt*100%。其中,Nc表示两个数集中相等的、两两互不相同的元素个数,而Nt表示两个数集中总共的互不相同的元素个数。请计算任意两个给出数集的相似程度。
Input
输入第一行给出一个正整数N(N<=50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(M<=5000),是集合中元素的个数;然后跟M个[0, 3000]区间内的整数。
之后一行给出一个正整数K(K<=800),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。
Output
输出共K行,每行一个保留2位小数的实数,表示给定两个集合的相似度值。
Sample Input
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
Sample Output
50.00%
33.33%
#include
using namespace std;
set<int>a[55];
int n,m,k,x,f,s;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>m;
while(m--){
cin>>x;
a[i].insert(x);
}
}
cin>>k;
while(k--){
cin>>f>>s;//first,second
set<int>::iterator it;
int cnt1=0,cnt2;
for(it=a[f].begin();it!=a[f].end();++it){
if(a[s].count(*it)) cnt1++;//对于a[f]中每个元素,如果a[s]中存在,cnt++
}
cnt2=a[f].size()+a[s].size()-cnt1;
printf("%.2lf%%\n",1.0*cnt1/cnt2*100.0);
}
return 0;
}
Description
某信息学奥赛教练经验丰富,他的内部题库有 m 道题。他有 n 个学生,第 i 个学生完成了p[i]道题。由于马上要进行 NOIP 的考试,该教练便举行了 k 场比赛和训练,每场比赛式训练都会有一些他的学生参加,但是如何选题令他非常烦恼。对于每场比赛,他要保证所出的题没有任何一道已有任何一个参赛学生做过;而对于每场训练,他要保证所出的所有题都被每一个参赛学生做过。
Input
第 1 行 2 个正整数 n 和 m,表示学生数和题库中的题目总量。
第 2~n+1 行,先是 1 个正整数 p(1<=p<=m),然后 p 个整数表示第 i 个学生的做题记录(可能重复做同一道题)。
第 n+2 行,1 个正整数 k,表示要举行的比赛和训练总数(可能有学生重复报名)。
接下来的 k 行,每行的第 1 个整数 type 表示是训练或者比赛(1 为训练,0 为比赛)。第 2个数 q(1<=q<=n) 表示参赛学生数,然后 q 个正整数表示参赛学生编号。每一行中的两个数之间有一个空格。
数据范围:1<=n,m,k<=1000
Output
共 k 行,每行表示本次训练或比赛可选的题目(由小到大排序,中间用一个空格隔开,注意本题输出格式是每行末尾也有一个空格,如果没有可选的题目输出一个空行)。
Sample Input
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
Sample Output
5
1 2 5 8 9
7
5 6 10
3
4 7
#include
using namespace std;
const int N=1e3+10;
int n,m,x,k,num,type;
set<int>s[N],quanji,ans;
set<int>::iterator it;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>num;
for(int j=1;j<=num;j++){
cin>>x;//选手i做过的题号为x(题目必须去重)
s[i].insert(x);
}
}
for(int i=1;i<=m;i++)
quanji.insert(i);//预处理全集
cin>>k;
while(k--){
cin>>type>>num;
ans=quanji;//两个set之间可以用等于号赋值
if(type==0){//比赛,他要保证所出的题都没有被任何一个参赛学生做过
for(int i=1;i<=num;i++){
cin>>x;//选手编号为x
for(it=ans.begin();it!=ans.end();){
if(s[x].count(*it))ans.erase(it++);//筛掉选手x做过的所有题
else it++;
}
}
}
else{//训练,他要保证所出的题都被每一个参赛学生做过
for(int i=1;i<=num;i++){
cin>>x;//选手编号为x
for(it=ans.begin();it!=ans.end();){
if(!s[x].count(*it))ans.erase(it++);//筛掉选手x没做过的所有题
else it++;
}
}
}
for(it=ans.begin();it!=ans.end();it++)
printf("%d ",*it);
printf("\n");
}
return 0;
}
Problem:G 昨天做过了
总结
set\<typename\> name;
insert();添加一个元素
erase();移除一个元素
count();判断某个元素是否存在
size();元素个数
clear();清空
erase(iterator) ,删除定位器iterator指向的值
erase(first,second),删除定位器first和second之间的值
erase(key_value),删除键值key_value的值
• set<int> s;
• set<int>::const_iterator iter; • set<int>::iterator first;
• set<int>::iterator second;
• for(int i = 1 ; i <= 200 ; ++i) • {s.insert(i);}
• //第一种删除
• s.erase(s.begin());
• //第二种删除
• first = s.begin();
• second = s.begin();
• second++; second++;
• s.erase(first,second);
• //第三种删除
• s.erase(18);
set只能通过迭代器访问。
set<typename>::iterator it;
for(it = s.begin() ; it != s.end() ; ++it) {
cout<<*it<<" ";
}
lower_bound(key_value) ,返回第一个大于等于key_value的定位器
upper_bound(key_value),返回最后一个大于等于key_value的定位器