寒假c++学习第四弹——常用STL练习(2021.01.28)

本文介绍了C++编程中常用的STL实践,包括堆积木问题的解决、集合并集计算、单词记忆判断、出现次数最多的数查找以及水果销售明细表生成。通过实例展示了如何利用STL容器和算法高效解决问题,同时涉及了数据结构的应用。
摘要由CSDN通过智能技术生成

寒假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;
}

如有错误欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值