天天看点

PAT乙级 1052 卖个萌 (20分)

1052 卖个萌 (20分)

萌萌哒表情符号通常由“手”、“眼”、“口”三个主要部分组成。简单起见,我们假设一个表情符号是按下列格式输出的:

现给出可选用的符号集合,请你按用户的要求输出表情。

输入格式:

输入首先在前三行顺序对应给出手、眼、口的可选符号集。每个符号括在一对方括号 []内。题目保证每个集合都至少有一个符号,并不超过 10 个符号;每个符号包含 1 到 4 个非空字符。

之后一行给出一个正整数 K,为用户请求的个数。随后 K 行,每行给出一个用户的符号选择,顺序为左手、左眼、口、右眼、右手——这里只给出符号在相应集合中的序号(从 1 开始),数字间以空格分隔。

输出格式:

对每个用户请求,在一行中输出生成的表情。若用户选择的序号不存在,则输出 Are you kidding me? @/@。

输入样例:

[╮][╭][o][~\][/~]  [<][>]
 [╯][╰][^][-][=][>][<][@][⊙]
[Д][▽][_][ε][^]  ...
4
1 1 2 2 2
6 8 1 5 5
3 3 4 3 3
2 10 3 9 3
           

输出样例:

╮(╯▽╰)╭
<(@Д=)/~
o(^ε^)o
Are you kidding me? @\/@
           

思路:

字符串处理的问题,难点在于输入。

还需要注意的地方是 Are you kidding me? @/@ 的’\‘符号是转义字符,需要写成‘\’

用户给出的序号下标是从1开始的。

统计数据:

PAT乙级 1052 卖个萌 (20分)

题解 方法一:

#include <cstdio>
#include <cstring>
using namespace std;

char emoj[5][20][20],st=0,tmpc,tmpemoj[10],tmpa;
int n,a,b,c,d,e;

int main(){
    while(st<3){
        scanf("%c",&tmpc);
        if(tmpc == 10 || tmpc == 13) st++;
        if(tmpc =='['){
            tmpa = 0;
            emoj[st][0][0]++;
            while(1){
                scanf("%c",&tmpc);
                if(tmpc==']') break;
                emoj[st][emoj[st][0][0]][tmpa++]=tmpc;
            }
            emoj[st][emoj[st][0][0]][tmpa++]='\0';
        }
    }
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
        if(a<=0 || b<=0 || c<=0 || d<=0 || e<=0 || a>emoj[0][0][0] || b>emoj[1][0][0] || c>emoj[2][0][0] || d>emoj[1][0][0] || e>emoj[0][0][0])
            printf("Are you kidding me? @\\/@\n");
        else
            printf("%s(%s%s%s)%s\n",emoj[0][a],emoj[1][b],emoj[2][c],emoj[1][d],emoj[0][e]);
    }
    return 0;
}
           

题解 方法二:

灵活运用正则表达式

#include <bits/stdc++.h>
using namespace std;

char emj[5][99][99],imp[1000],tmp[100],cnt[5],tmpa;
int a,b,c,d,e,n;

int main(){
    for(int i=0;i<3;++i){
        scanf("%[^\n]%c",imp,&tmpa); //tmp是为了吸收换行符 等同于getchar();
        for(char *p=imp;*p;p++)
            if(*p=='['){
                sscanf(p+1,"%[^]]",tmp); //正则表达式是个很好用的东西。
                strcpy(emj[i][++cnt[i]],tmp);
            }
    }
    scanf("%d",&n);
    while(n--){
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
        if(a<=0 || b<=0 || c<=0 || d<=0 || e<=0 || a>cnt[0] || b>cnt[1] || c>cnt[2] || d>cnt[1] || e>cnt[0])
            printf("Are you kidding me? @\\/@\n"); //注意上边这一行 用a*b*c*d*e<=0来判断他们是否有小于0的方法,是不行的
        else
            printf("%s(%s%s%s)%s\n",emj[0][a],emj[1][b],emj[2][c],emj[1][d],emj[0][e]);
    }
    return 0;
}
           

题解 方法三:

搬运一个日沉云起大佬的代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main() {
    ios::sync_with_stdio(false);
    array<vector<string>, 3> e{};  //存储表情符号
    for (auto& v : e) {
        string line;
        getline(cin, line);  //读取一行字符串
        // i负责查找'['的下标,j负责查找']'的下标
        for (auto i = line.find('['); i != -1;) {
            auto j = line.find(']', i);
            v.push_back(line.substr(i + 1, j - i - 1));
            i = line.find('[', j);
        }
    }
    gg k, a;
    cin >> k;
    while (k--) {
        string out;  //存储要输出的表情字符串
        bool f = true;  //表示下标是否存在非法情况
        for (auto i = 0; i < 5; ++i) {
            cin >> a;
            // v负责获取a是手眼口中哪个表情数组的下标
            const auto& v = i == 2 ? e[2] : (i == 0 or i == 4) ? e[0] : e[1];
            if (a - 1 >= v.size()) {  //下标非法
                f = false;
            } else {
                out += v[a - 1] + (i == 0 ? "(" : i == 3 ? ")" : "");
            }
        }
        f ? cout << out << '\n' : cout << "Are you kidding me? @\\/@\n";
    }
    return 0;
}