寒假c++学习第四弹——常用STL练习(2021.01.28)
目录
1.堆积木
2.计算集合的并
3.学英语
4.面试
5.水果店
1.堆积木
题目描述:
有n块积木,编号分别为1到n。一开始,我们把第i块积木放在位置i上。进行m次操作,每次操作,把位置b上的积木整体移动到位置a上面。比如1位置的积木是1,2位置的积木是2,那么把位置2的积木移动到位置1后,位置1上的积木从下到上依次为1,2。
输入格式:
第一行输入2个整数n,m(1 <= n <= 10000, 0 <= m <= 10000).接下来m行,每行输入2个整数a,b(1<= a, b <= n),如果a,b相等则本次不需要移动。
输出格式:
输出n行,第i行输出位置i从上到下的积木编号
输入样例1:
2 2
1 2
1 2
输出样例1:
1 2
输入样例2:
4 4
3 1
4 3
2 4
2 2
输出样例2:
2 4 3 1
参考代码
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
vector<int> v[10005];
int main(){
int n, m, a, b;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++){
v[i].push_back(i);
}
for(int i=0; i<m; i++){
scanf("%d%d", &a, &b);
if(a==b){
continue;
}
for(int j=0; j<v[b].size(); j++){
v[a].push_back(v[b][j]);
}
vector<int>().swap(v[b]); //Çå³ýÄÚ´æ
}
for(int i=1; i<=n; i++){
for(int j=0; j<v[i].size(); j++){
if(j != v[i].size()-1){
printf("%d ", v[i][j]);
}else{
printf("%d", v[i][j]);
}
}
printf("\n");
}
return 0;
}
2.计算集合的并
题目描述:
给出两个集合,计算其并集,即{A} + {B}。注:{A} + {B}中不允许出现重复元素,但是{A} 与 {B}之间可能存在相同元素。
输入格式:
输入三行数据,第一行有两个数字n,m(0 < n, m <= 10000),分别表示集合A和集合B的元素个数,后两行分别表示集合A和集合B。每个元素为不超出int范围的整数,每个元素之间用一个空格隔开。
输出格式:
输出一行数据,表示合并后的集合,要求从自傲到达输出,每个元素之间用一个空格隔开。
输入样例1:
1 2
1
2 3
输出样例1:
1 2 3
输入样例2:
1 2
1
1 2
输出样例2:
1 2
参考代码
#include <iostream>
#include <set>
using namespace std;
set<int> s;
int main(){
int n, m, x, cnt=0;
cin >> n >> m;
for(int i=0; i<n+m; i++){
cin >> x;
s.insert(x);
}
for(set<int>::iterator it = s.begin(); it != s.end(); it++){
if(cnt != s.size()-1){
cout << *it << " ";
}else{
cout << *it << endl;
}
}
return 0;
}
3.学英语
题目描述:
快要考托福了,这几天,小k每天早上都起来记英语单词。小v时不时地来考一考小k:小v会询问小k一个单词,如果小k背过这个单词,小k会告诉小v这个单词的意思,不然小k会跟小v说还没有背过。单词是由连续的大写或者小写字母组成。注意单词中字母大小写是等价的。比如You和you是一个单词。
输入格式:
首先输入一个n(1 <= n <= 100000)表示事件数。接下来n行,每行表示一个事件。每个事件输入为一个整数d和一个单词 word(单词长度不大于20),用空格隔开。如果d=0,表示小k记住了 word这个单词,如果d=1,表示这是个测试,测试蒜头君是否认识单词word(小v永远不会告诉小k这个单词的意思) 事件的输入是按照时间先后顺序输入的。
输出格式:
对于小v的每次测试,如果小k认识这个单喜,输出一行Yes,否则输出一行No。
输入样例1:
5
0 we
0 are
1 family
0 Family
1 Family
输出样例1:
No
Yes
输入样例2:
4
1 xiaok
0 xiaok
0 XIAOK
1 XIAOK
输出样例2:
No
Yes
参考代码
#include <set>
using namespace std;
set<string> s;
string ss;
int main(){
int n, op;
cin >> n;
for(int i=0; i<n; i++){
cin >> op >> ss;
for(int j=0; j<ss.size(); j++){
if(ss[j] >= 'A' && ss[i] <= 'Z'){
ss[j] = 'a' + (ss[j] - 'A');
}
}
if(op==0){
s.insert(ss);
}else{
if(s.count(ss)){
cout << "Yes" << endl;
}
else{
cout << "No" << endl;
}
}
}
return 0;
}
4.面试
题目描述:
给定n个整数,求里面出现次数最多的数,如果有多个重复出现的数,求出值最大的一个。
输入格式:
第一行输入一个整数n(1 <= n <= 100000),接下来一行输入n个int范围内的整数。
输出格式:
输出出现次数最多的数和出现的次数,中间用一个空格隔开,如果有多个重复出现的数,输出值最大的那个。
输入样例1:
5
1 1 2 3 4
输出样例1:
1 2
输入样例2:
10
9 10 27 4 9 10 3 1 2 6
输出样例2:
10 2
参考代码
#include <iostream>
#include <map>
using namespace std;
map<int, int> mp;
int main(){
int n, x, ans1, ans2;
cin >> n;
for(int i=0; i<n; i++){
cin >> x;
mp[x]++;
}
ans1=0;
ans2=0;
for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++){
if((it -> second) >= ans2){
ans2 = it->second;
ans1 = it->first;
}
}
cout << ans1 << " " <<ans2;
return 0;
}
5.水果店
题目描述:
f镇有一个水果店,店长想要一份水果销售情况明细表,他会告诉我们每一笔销售记录的水果名称,产地和销售数量,请你帮他生成明细表。
输入格式:
第一行是一个整数N(0 < N <= 1000).表示共有N次成功交易,其后有N行,每行表示一次交易,由水果名称(小写字母组成,长度不超过100),水果产地(小写字母组成,长度不超过100)和交易数量(正整数,不超过1000)组成。
输出格式:
输出一份排版格式正确的水果销售明细表。这份明细表包括所有水果的产地、名称和销售数目信息。水果先按产地分类,产地按字母顺序排列;同一产地水果按照名称排序,名称按字母顺序排列。
输入样例:
5
apple shandong 3
pineapple guangdong 1
sugarcane guangdong 1
pineapple guangdong 3
pineapple guangdong 1
输出样例:
guangdong
|----pineapple(5)
|----sugarcane(1)
shandong
|----apple(3)
参考代码
#include <iostream>
#include <string>
#include <map>
using namespace std;
map<string, map<string, int> > mp; //产地-->水果名,数量
string s1, s2;
int d;
int main(){
int n;
cin >> n;
for(int i=0; i<n; i++){
cin >> s1 >> s2 >> d;
mp[s2][s1] += d;
}
for(map<string, map<string, int> >::iterator it1 = mp.begin(); it1 != mp.end(); it1++){
cout << (it1 -> first) << endl;
for(map<string, int>::iterator it2 = (it1->second).begin(); it2 != (it1->second).end(); it2++){
cout << " |----" << (it2->first) << "(" << (it2->second) << ")" << endl;
}
}
return 0;
}
如有错误欢迎指正。