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<<"\n"<<r[i].addr<<" "<<r[i].data;
    cout<<" "<<-1;
    return 0;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM