PAT甲级备考——map、set、STL

PAT甲级备考——map、set、STL

  • 题目
    • 【1112】map、字符串处理
    • 【1121】map、set(find\insert\erase)
    • 【1149】 map、STL、int exist[100000] = {0}判断ID是否存在
    • 【1124】map、STL
    • 【1100】 map、STL、getchar()、getline()、cin
    • 【1022】map.find(), vector

题目

PAT (Advanced Level) Practice

【1112】map、字符串处理
【1121】map、set(find\insert\erase)
【1124】map简单()
【1149】 map、STL、int exist[100000] = {0}判断ID是否存在
【1100】 map、STL、getchar()、getline()、cin
【1071】map、isalnum()cctype判断是否是数字和大小写字母()
【1054】map 简单
【1022】map.find(), vector>>多重, while(cin>>keyword) 持续输入, substr(3)从第三个到结尾  

set:

【1063】 Set Similarity (25) [集合set,STL的使⽤]
【1120】 Friend Numbers (20) [set的应⽤]
【1121】 Damn Single (25) [set的应⽤]
【1129】 Recommendation System (25) [set的应⽤,运算符重载]
【1154】Vertex Coloring (25) [set,hash] 

【1112】map、字符串处理

题目大意:键盘某些键卡住了,按⼀次重复k次,要求找出可能的键,并且输出正确的字符串顺序。可能的键要求按照被发现的顺序输出。
注意:
(1)认真读题!!!!
(2)如果某个键是坏的,则一定会连续输出k的整数倍次数
因此,如果有一个字符连续输出k的整数倍次,可以置might_bad为true
但是,如果有一个字符连续输出不是k的整数倍,则一定不是坏键,sure_not_bad为true
要在might_bad中找到sure_not_bad为true的,更新
(3)可以像遍历数组一样遍历字符串: for(int i=1; i (4)string[i] 就是char类型字符

#include
#include
#include
#include
using namespace std;
int main(){
    int k;
    string data;
    scanf("%d", &k);
    cin>>data;
    map<char, bool> might_bad; // 所有连续计数为k的字符都可能时坏的
    map<char, bool> sure_not_bad; // 但如果当前出现的次数确定小于k,则无论之后是否出现k个连续,都不是坏键
    unordered_set<char> bad_key;
    int pre = data[0];
    int cnt = 1;
    for(int i=1; i<data.length(); i++){
        if(data[i] == pre) cnt++;
        else{ // 如果前后两个字符不相等,且pre字符的计数cnt不能整除k,则pre一定不是坏键
            if(cnt%k!=0) sure_not_bad[pre] = true; // 这里比如k=3,但如果连续出现5个a,则a不是坏键,因为若是坏则一定是3的整数倍
            cnt = 1;
        }
        might_bad[data[i]] = ((cnt%k)==0);
        pre = data[i];
    }
    // 从可能是坏键中排除确定不是坏的
    for(int i=0; i<data.length(); i++){
        if(sure_not_bad[data[i]]) might_bad[data[i]] = false;
    }
    // 输出坏键,set保证每个只输出一次
    for(int i=0; i<data.length(); i++){
        if(might_bad[data[i]]){
            if(bad_key.find(data[i])==bad_key.end()){
                cout<<data[i];
            }
            bad_key.insert(data[i]);
        }
    }
    cout<<endl;
    // 输出坏键修复后的字符串
    for(int i=0; i<data.length(); ){
        cout<<data[i];
        if(!might_bad[data[i]]){
            i++;
        }else{
            i += k;
        }
    }
    return 0;
}

【1121】map、set(find\insert\erase)

1121 Damn Single (25 分)
给出couple的信息,在party中couple成对出现则认为不是单身狗,否则认为是单身狗;找出所有单身狗的人。
party中的人保存在set中,couple保存成map,遍历map,若两个人都在set中,则从set中erase。最终set的大小为所有单身狗的数目。

#include
#include
#include
using namespace std;
int main(){
    // 输入couple信息,保存在映射map中
    map<int, int> couple;
    set<int> party;
    int N, M, c1, c2, p1;
    cin>>N;
    while(N--){
        scanf("%d %d", &c1, &c2);
        couple[c1] = c2;
    }
    // 输入参加party的人的信息,保存在set中
    cin>>M;
    for(int i=0; i<M; i++){
        scanf("%d", &p1);
        party.insert(p1);
    }
    // 遍历map,若key和value同时出现在set中,则从set中删除两个人(不是单身狗)
    for(auto it = couple.begin(); it!=couple.end(); it++){
        if((party.find(it->first)!=party.end()) && (party.find(it->second)!=party.end())){
            party.erase(it->first);
            party.erase(it->second);
        }
    }
    
    // 遍历输出set中的元素
    cout<<party.size()<<endl;
    int num = 0;
    for(auto iter=party.begin(); iter!=party.end(); iter++){
        num++;
        printf("%05d%s", *iter, num==party.size()?"\n":" ");
    }
    
}

【1149】 map、STL、int exist[100000] = {0}判断ID是否存在

1149 Dangerous Goods Packaging

思路:
首先先将所有无法共存的id,存放在incompatible map映射中,是int到vector的映射;
接着输入所有需要判断的新的id,存入exist_id中;
并且维持一个exist的判断数组,对于新输入的id,exist[id]置为1,否则置为0;
遍历所有incompatible中的映射,若存在于exist,则无法共存,判断compatible为false;

#include
#include
#include
using namespace std;

int main(){
    int N, M;
    cin>>N>>M;
    int a,b;
    map<int, vector<int>> incompatible; // 无法一起存放的物质,存放在map中
    for(int i=0; i<N; i++){
        scanf("%d %d",&a,&b);
        incompatible[a].push_back(b);
        incompatible[b].push_back(a);
    }
    
    while(M--){
        int K, id;
        bool compatible = true;
        int exist[100000] = {0}; // 存在的id,若存在则置为1
        cin>>K;
        vector<int> exist_id(K);  
        for(int i=0; i<K; i++){
            scanf("%d",&id);
            exist_id[i] = id;
            exist[id] = 1;
        }
        // 遍历所有无法共存的id映射,若同时存在于exist_id,则表示无法共存,compatible置为false
        for(int i=0; i<exist_id.size(); i++){
            for(int j=0; j<incompatible[exist_id[i]].size(); j++){
                int id1 = exist_id[i];
                int id2 = incompatible[exist_id[i]][j];
                if(exist[id1] && exist[id2]){
                    compatible = false;
                    break;
                }
            }
        }
        printf("%s\n",compatible==true ? "Yes":"No");
    }
    return 0;
}

【1124】map、STL

1124 Raffle for Weibo Followers (20 分)
map:用于映射已经是winner的人名和被选中的次数

#include
#include
using namespace std;
unordered_map<string, int> winner; // 用于映射已经是winner的人名和被选中的次数
int main(){
    int m, n, s;
    scanf("%d %d %d", &m, &n, &s);
    string w;
    bool has_winner = false;
    for(int i=1; i<=m; i++){
        cin>>w;
        if(winner[w]==1) s =  s + 1; // 如果这个人已经被选中了,则consider the next one
        if(i==s && winner[w]!=1){ // 注意n是跳过的人数,因此下面要s=s+n
            cout<<w<<endl;
            s = s + n;
            winner[w]++;
            has_winner = true;
        }
    }
    if(!has_winner) cout<<"Keep going..."<<endl;
    return 0;
}

【1100】 map、STL、getchar()、getline()、cin

1100 Mars Numbers (20 分)
Mars计数方式和Earth计数方式转换

读取数据:
getchar() 可用于读取字符,用于读取多余的’\n’
对于代码
char test1 = getchar();
char test2 = getchar();
此时在控制台中输入字符“a”并且按下回车键,test1的值是字符“a”,而test2的值是“\n”

getline() 函数可读取整行,包括前导和嵌入的空格,并将其存储在字符串对象中

cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取
cin可以输入 “Mark” 或 “Twain”,但不能输入 “Mark Twain”,因为cin不能输入包含嵌入空格的字符串。

#include
#include
#include
using namespace std;
string etm1[13] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string etm2[13] = {"NONE","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};

bool is_mars(string s){
    return (s[0]-'0' >=49);
}
void to_earth(string s){
    int t1 = 0, t2 = 0;
    string s1 = s.substr(0,3), s2;
    if(s.length()>4) s2 = s.substr(4,3);
//     if(s1=="tre") s1 = "tret";
//     if(s2=="tre") s2 = "tret";
    for(int i=1; i<=12; i++){
        if(s1==etm1[i] || s2==etm1[i]) t1 = i;
        if(s1==etm2[i]) t2 = i;
    }
    cout<<(t2*13+t1)<<endl;
}
void to_mars(string s){
    int pre = stoi(s)/13;
    int sec = stoi(s)%13;
    if(pre > 0){
        cout<<etm2[pre];
        if(sec!=0) cout<<" "<<etm1[sec]<<endl;
        else cout<<endl;
    }else{
        cout<<etm1[sec]<<endl;
    }
    
}
int main(){
    int N;
    string s;
    cin>>N;
    getchar();
    while(N--){
        getline(cin, s);
        if(is_mars(s)) to_earth(s);
        else to_mars(s);
    }
    return 0;
}1054】map 简单

1054 The Dominant Color (20)


#include
#include
using namespace std;
int main(){
    int M, N, a;
    map<int, int> m;
    scanf("%d %d", &M, &N);
    for(int i=0; i<N; i++){
        for(int j=0; j<M; j++){
            scanf("%d", &a);
            m[a]++;
        }
    }
    int max_num = 0;
    int dominant = -1;
    for(auto it=m.begin(); it!=m.end(); it++){
        if(it->second > max_num){
            max_num = it->second;
            dominant = it->first;
        }
    }
    cout<<dominant<<endl;
}

【1022】map.find(), vector>多重, while(cin>>keyword) 持续输入, substr(3)从第三个到结尾

1022 Digital Library (30 分)
(1)设置数组保存map,map1: title, map2: author, map3: keywords, map4: publisher, map5: year
每个map为string到string_set的映射,具体内容到ID集合的映射
(2)通过getline和while(cin>>k)输入
(3)查询:map也可以通过find判断某个key是否在map中,若key在map中,则遍历key对应的set,输出

#include
#include
#include
#include
#include
using namespace std;
int main(){
    string sN, ID, title, author, keywords, publisher, year;
    getline(cin, sN);
    int N = stoi(sN);
    // 设置数组保存map,map1: title, map2: author, map3: keywords, map4: publisher, map5: year
    // 每个map为string到string_set的映射,具体内容到ID集合的映射
    vector<map<string, set<string>>> vm;
    vm.resize(6);


    for(int i=0; i<N; i++){
        getline(cin, ID);
        
        getline(cin, title);
        vm[1][title].insert(ID);
        
        getline(cin, author);
        vm[2][author].insert(ID);
        
        // 输入关键词test code debug sort keywords,关键词之间空格间隔,分别读入关键词
        // 方法1
        while(cin>>keywords){
            vm[3][keywords].insert(ID);
            char c = getchar();
            if(c=='\n') break;
        }
        
        /*
        // 方法2
        getline(cin, keywords);
        string t;
        int l = keywords.length();
        for(int i=0; i
        getline(cin, publisher);
        vm[4][publisher].insert(ID);
        
        getline(cin, year);
        vm[5][year].insert(ID);
    }
    
    string sk, t1;
    getline(cin, sk);
    int k = stoi(sk);
    while(k--){
        getline(cin, t1);
        cout<<t1<<endl; // 1: The Testing Book
        // 每行第一个字符为judge
        int judge = stoi(t1.substr(0,1));
        // 第三个字符之后是具体的map中的key
        string t2 = t1.substr(3);
        
//         scanf("%d: ", &num);
//         string temp;
//         getline(cin, temp);
//         cout << num << ": " << temp << "\n";
        
        // map也可以通过find判断某个key是否在map中
        // 若key在map中,则遍历key对应的set,输出
        if(vm[judge].find(t2) != vm[judge].end()){
            for(auto it=vm[judge][t2].begin(); it!=vm[judge][t2].end(); it++)
                cout<<*it1<<endl;
        }else{
            cout<<"Not Found"<<endl;
        }
    }
    return 0;
}

你可能感兴趣的:(PAT,c++,数据结构,算法)