PAT-2019年冬季考试-乙级(题解)

很荣幸这次能够参加乙级考试,和大佬们同台竞技了一次,这篇博客,进行介绍这次2019冬季的乙级考试题解。

7-1 2019数列 (15分)

把 2019 各个数位上的数字 2、0、1、9 作为一个数列的前 4 项,用它们去构造一个无穷数列,其中第 n(>)项是它前 4 项之和的个位数字。例如第 5 项为 2, 因为 2,个位数是 2。

本题就请你编写程序,列出这个序列的前 n 项。

输入格式:

输入给出正整数 n(≤)。

输出格式:

在一行中输出数列的前 n 项,数字间不要有空格。

输入样例:

10

输出样例:

2019224758

题外话:这个数列中永远不会出现 2018,你能证明吗?

这道题目的解题思路,使用一个数组,长度为N+1,之后进行遍历,将前四位的数求和并且模一个10,就可以得到最终结果。

最终遍历,将结果打印即可

#include <iostream>
using namespace std;
int main()
{
    int N;cin>>N;
    int a[N+1];
    a[1]=2;
    a[2]=0;
    a[3]=1;
    a[4]=9;
    for(int i=5;i<=N;i++)
        a[i]=(a[i-1]+a[i-2]+a[i-3]+a[i-4])%10;
    for(int i=1;i<=N;i++)
        cout<<a[i];
    return 0;
}

7-2 老鼠爱大米 (20分)

翁恺老师曾经设计过一款 Java 挑战游戏,叫“老鼠爱大米”(或许因为他的外号叫“胖胖鼠”)。每个玩家用 Java 代码控制一只鼠,目标是抢吃尽可能多的大米让自己变成胖胖鼠,最胖的那只就是冠军。

因为游戏时间不能太长,我们把玩家分成 N 组,每组 M 只老鼠同场竞技,然后从 N 个分组冠军中直接选出最胖的冠军胖胖鼠。现在就请你写个程序来得到冠军的体重。

输入格式:

输入在第一行中给出 2 个正整数:N(≤)为组数,M(≤)为每组玩家个数。随后 N 行,每行给出一组玩家控制的 M 只老鼠最后的体重,均为不超过 1 的非负整数。数字间以空格分隔。

输出格式:

首先在第一行顺次输出各组冠军的体重,数字间以 1 个空格分隔,行首尾不得有多余空格。随后在第二行输出冠军胖胖鼠的体重。

输入样例:

3 5
62 53 88 72 81
12 31 9 0 2
91 42 39 6 48

输出样例:

88 31 91
91

这道题考的是求最大值,我们使用遍历直接进行比较,求最大值的方法,来求解最大值。随后,之后,进行求最大值的最大值即可

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int M,N;int tmp,tmp_m,m=-1;
    cin>>M>>N;
    vector<int> v;
    while(M--){
        tmp_m=-1;
        for(int i=0;i<N;i++){
            cin>>tmp;
            if(tmp>tmp_m) tmp_m=tmp;
        }
        v.push_back(tmp_m);
        if(tmp_m>m) m=tmp_m;
    }
    for(int i=0;i<v.size();i++)
        if(i!=v.size()-1) cout<<v[i]<<" ";
        else cout<<v[i]<<endl;
    cout<<m<<endl;
    return 0;
}

7-3 String复读机 (20分)

给定一个长度不超过 1 的、仅由英文字母构成的字符串。请将字符重新调整顺序,按 StringString.... (注意区分大小写)这样的顺序输出,并忽略其它字符。当然,六种字符的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按 String 的顺序打印,直到所有字符都被输出。例如 gnirtSSs 要调整成 StringS 输出,其中 s 是多余字符被忽略。

输入格式:

输入在一行中给出一个长度不超过 1 的、仅由英文字母构成的非空字符串。

输出格式:

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

输入样例:

sTRidlinSayBingStrropriiSHSiRiagIgtSSr

输出样例:

StringStringSrigSriSiSii

这道题目,我的思路是,使用getline函数进行获取一行的字符串,然后紧接着,遍历字符串,进行计数String这几个字母分别有多少,

最终,我们可以使用依次遍历打印的方式,获得想要的答案

#include <iostream>
#include <map>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    map<char,int> m;
    m['S']=0; m['t']=1; m['r']=2; m['i']=3; m['n']=4; m['g']=5;
    int arr[6]={0};
    for(int i=0;i<s.length();i++)
        if(s[i]=='S'||s[i]=='t'||
           s[i]=='r'||s[i]=='i'||
           s[i]=='n'||s[i]=='g')
            arr[m[s[i]]]++;
    while(true){
        if(arr[0]==0&&arr[1]==0&&arr[2]==0&&
           arr[3]==0&&arr[4]==0&&arr[5]==0) break;
        for(int i=0;i<6;i++){
            if(arr[i]!=0) {
                switch(i){
                    case 0:cout<<"S";break;
                    case 1:cout<<"t";break;
                    case 2:cout<<"r";break;
                    case 3:cout<<"i";break;
                    case 4:cout<<"n";break;
                    case 5:cout<<"g";break;
                }
                arr[i]--;
            }
            else continue;
        }
    }
    return 0;
}

7-4 擅长C (20分)

当你被面试官要求用 C 写一个“Hello World”时,有本事像下图显示的那样写一个出来吗?

HWC.jpg

输入格式:

输入首先给出 26 个英文大写字母 A-Z,每个字母用一个 7 的、由 C 和 . 组成的矩阵构成。最后在一行中给出一个句子,以回车结束。句子是由若干个单词(每个包含不超过 10 个连续的大写英文字母)组成的,单词间以任何非大写英文字母分隔。

题目保证至少给出一个单词。

输出格式:

对每个单词,将其每个字母用矩阵形式在一行中输出,字母间有一列空格分隔。单词的首尾不得有多余空格。

相邻的两个单词间必须有一空行分隔。输出的首尾不得有多余空行。

输入样例:

..C..
.C.C.
C...C
CCCCC
C...C
C...C
C...C
CCCC.
C...C
C...C
CCCC.
C...C
C...C
CCCC.
.CCC.
C...C
C....
C....
C....
C...C
.CCC.
CCCC.
C...C
C...C
C...C
C...C
C...C
CCCC.
CCCCC
C....
C....
CCCC.
C....
C....
CCCCC
CCCCC
C....
C....
CCCC.
C....
C....
C....
CCCC.
C...C
C....
C.CCC
C...C
C...C
CCCC.
C...C
C...C
C...C
CCCCC
C...C
C...C
C...C
CCCCC
..C..
..C..
..C..
..C..
..C..
CCCCC
CCCCC
....C
....C
....C
....C
C...C
.CCC.
C...C
C..C.
C.C..
CC...
C.C..
C..C.
C...C
C....
C....
C....
C....
C....
C....
CCCCC
C...C
C...C
CC.CC
C.C.C
C...C
C...C
C...C
C...C
C...C
CC..C
C.C.C
C..CC
C...C
C...C
.CCC.
C...C
C...C
C...C
C...C
C...C
.CCC.
CCCC.
C...C
C...C
CCCC.
C....
C....
C....
.CCC.
C...C
C...C
C...C
C.C.C
C..CC
.CCC.
CCCC.
C...C
CCCC.
CC...
C.C..
C..C.
C...C
.CCC.
C...C
C....
.CCC.
....C
C...C
.CCC.
CCCCC
..C..
..C..
..C..
..C..
..C..
..C..
C...C
C...C
C...C
C...C
C...C
C...C
.CCC.
C...C
C...C
C...C
C...C
C...C
.C.C.
..C..
C...C
C...C
C...C
C.C.C
CC.CC
C...C
C...C
C...C
C...C
.C.C.
..C..
.C.C.
C...C
C...C
C...C
C...C
.C.C.
..C..
..C..
..C..
..C..
CCCCC
....C
...C.
..C..
.C...
C....
CCCCC
HELLO~WORLD!

输出样例:

C...C CCCCC C.... C.... .CCC.
C...C C.... C.... C.... C...C
C...C C.... C.... C.... C...C
CCCCC CCCC. C.... C.... C...C
C...C C.... C.... C.... C...C
C...C C.... C.... C.... C...C
C...C CCCCC CCCCC CCCCC .CCC.

C...C .CCC. CCCC. C.... CCCC.
C...C C...C C...C C.... C...C
C...C C...C CCCC. C.... C...C
C.C.C C...C CC... C.... C...C
CC.CC C...C C.C.. C.... C...C
C...C C...C C..C. C.... C...C
C...C .CCC. C...C CCCCC CCCC.

这道题目,考了一道输出格式化。我觉得是5题中最有难度的一题。

我们可以使用一个嵌套的vector进行存储字符串,然后进行调整打印的方式,进行输出。

这边要注意几点:

1.如果你有2个测试用例没过,很可能你没有考虑到,遍历断开字符串的时候,把最后一个字符串

加入vector,比如,试下hello这个用例

2.如果你有3个测试用例没有过,可能你的限定范围不够,例如:你的字符是限定在A-Z么?还是说你使用了

isalpha函数进行判断了,当然,你也可以使用isUpper函数进行判断,这也是可行的

#include <iostream>
#include <vector>
using namespace std;
vector<vector<string>> v;
void out(string& s){
    for(int i=0;i<7;i++){
        for(int j=0;j<s.size();j++){
            if(j!=s.size()-1) cout<<v[s[j]-'A'][i]<<" ";
            else cout<<v[s[j]-'A'][i]<<endl;
        }
    }
}
int main(){
    string s;
    for(int i=0;i<26;i++){
        vector<string> tmp_v;
        string tmp;
        for(int j=0;j<7;j++){
            getline(cin,tmp);
            tmp_v.push_back(tmp);
        }
        v.push_back(tmp_v);
    }
    string in;
    getline(cin,in);
    vector<string> v_word;
    string s2="";
    for(int i=0;i<in.size();i++){
        if(in[i]>='A'&&in[i]<='Z') s2+=in[i];
        else {
            if(s2!="") v_word.push_back(s2);
            s2="";
        }
    }
    if(s2!="") v_word.push_back(s2);
    for(int i=0;i<v_word.size();i++)
        if(i==v_word.size()-1) out(v_word[i]);
        else {
            out(v_word[i]);
            cout<<endl;
        }
    return 0;
}

7-5 区块反转 (25分)

给定一个单链表 L,我们将每 K 个结点看成一个区块(链表最后若不足 K 个结点,也看成一个区块),请编写程序将 L 中所有区块的链接反转。例如:给定 L 为 1→2→3→4→5→6→7→8,K 为 3,则输出应该为 7→8→4→5→6→1→2→3。

输入格式:

每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤)、以及正整数 K (≤),即区块的大小。结点的地址是 5 位非负整数,NULL 地址用 − 表示。

接下来有 N 行,每行格式为:

Address Data Next

其中 Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:

00100 8 3
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218

输出样例:

71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1

这道题是常见的链表反转,主要解题方式是,利用vector进行模拟链表,进行翻转后格式化打印,

然后,这道题的注意点是,刚开始要使用一个unordered_map进行存储,因为在遍历查找时,很有可能,

因为这个查找而超时

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct node{
    string addr;
    int data;
    string next;
};
int main(){
    string start;int M,N;
    map<string,node> m;
    node tmp;
    vector<node> v;
    v.push_back(tmp);
    cin>>start>>M>>N;
    while(M--){
        cin>>tmp.addr>>tmp.data>>tmp.next;
        m[tmp.addr]=tmp;
    }
    while(start!="-1"){
        v.push_back(m[start]);
        start=m[start].next;
    }
    vector<vector<node>> res;
    for(int i=1;i<v.size();i++){
        vector<node> tmp_v;
        while(true){
            tmp_v.push_back(v[i]);
            if(i%N==0||i==v.size()-1) break;
            i++;
        }
        res.push_back(tmp_v);
    }
    reverse(res.begin(),res.end());
    vector<node> r;
    for(int i=0;i<res.size();i++)
        for(int j=0;j<res[i].size();j++)
            r.push_back(res[i][j]);
    for(int i=0;i<r.size();i++)
        if(i==0) cout<<r[i].addr<<" "<<r[i].data;
        else cout<<" "<<r[i].addr<<"
"<<r[i].addr<<" "<<r[i].data;
    cout<<" "<<-1;
    return 0;
}
原文地址:https://www.cnblogs.com/littlepage/p/12004042.html