1. 程式人生 > >PAT A1152-A1155題解報告(即PAT 2018.12.9冬季甲級考試題)

PAT A1152-A1155題解報告(即PAT 2018.12.9冬季甲級考試題)

1152 Google Recruitment (20 分)

In July 2004, Google posted on a giant billboard along Highway 101 in Silicon Valley (shown in the picture below) for recruitment. The content is super-simple, a URL consisting of the first 10-digit prime found in consecutive digits of the natural constant e. The person who could find this prime number could go to the next step in Google's hiring process by visiting this website.

prime.jpg

The natural constant e is a well known transcendental number(超越數). The first several digits are: e = 2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921... where the 10 digits in bold are the answer to Google's question.

Now you are asked to solve a more general problem: find the first K-digit prime in consecutive digits of any given L-digit number.

Input Specification:

Each input file contains one test case. Each case first gives in a line two positive integers: L (≤ 1,000) and K (< 10), which are the numbers of digits of the given number and the prime to be found, respectively. Then the L-digit number N is given in the next line.

Output Specification:

For each test case, print in a line the first K-digit prime in consecutive digits of N. If such a number does not exist, output 404instead. Note: the leading zeroes must also be counted as part of the K digits. For example, to find the 4-digit prime in 200236, 0023 is a solution. However the first digit 2 must not be treated as a solution 0002 since the leading zeroes are not in the original number.

Sample Input 1:

20 5
23654987725541023819

Sample Output 1:

49877

Sample Input 2:

10 3
2468024680

Sample Output 2:

404

題意:找url中的出現的第一個k位素數,0佔位。有則輸出這個素數,沒輸出404;

思路:字串處理加素數判斷

將長度為L的數字當做字串輸入,然後對字串進行遍歷擷取子串長度為k的字串進行字串轉數字,通過isPrime()判斷結果,如果當前遍歷到的字串是素數,則輸出字串,並跳出for迴圈;

考點:1.字串串處理;2.素數判斷;3字串轉數字;4.進位制轉換(最笨的方法了吧)

坑點:1.首先得判斷k和l的大小關係,如果k>l,那麼答案自然是404;

          2.前導零的處理,如果當做字串輸出這個問題就很簡單的通過stoi或atoi處理去掉了前導零,如果不是的話的通過ASCII碼運算+進位制 轉換。

          3.素數判斷相關坑點,《演算法筆記》中將解了三個方法,這裡採取了第一個方法判斷。

          4.注意迴圈結束條件為i<=url.size()-k;

         這題考試時得了19分,用了大概30分鐘,還有個測試點好像是素數處理時2的判斷沒寫;這也是這次參加考試的總得分,真的慘;

#include <bits/stdc++.h>

using namespace std;

bool isPrime(int x){
    if(x<=1)return false;
    int sqr=sqrt(x);
    if(x==2)return true;
    for(int i=2;i<=sqr;i++){
        if(x%i==0)return false;
    }
    return true;
}
int main()
{
    int l,k;
    string url;
    cin>>l>>k>>url;
     if(k>l){
        cout<<"404";
        return 0;
    }
    for(int i=0;i<=url.size()-k;i++){
        string t_str=url.substr(i,k);
        //cout<<"Test:"<<t_str<<endl;
        int t_num=stoi(t_str);
        bool flag=isPrime(t_num);
        if(flag){
            cout<<t_str;
            return 0;
        }
    }
    cout<<"404";
    return 0;
}

1153 Decode Registration Card of PAT (25 分)

A registration card number of PAT consists of 4 parts:

  • the 1st letter represents the test level, namely, T for the top level, A for advance and B for basic;
  • the 2nd - 4th digits are the test site number, ranged from 101 to 999;
  • the 5th - 10th digits give the test date, in the form of yymmdd;
  • finally the 11th - 13th digits are the testee's number, ranged from 000 to 999.

Now given a set of registration card numbers and the scores of the card owners, you are supposed to output the various statistics according to the given queries.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (≤10​4​​) and M (≤100), the numbers of cards and the queries, respectively.

Then N lines follow, each gives a card number and the owner's score (integer in [0,100]), separated by a space.

After the info of testees, there are M lines, each gives a query in the format Type Term, where

  • Type being 1 means to output all the testees on a given level, in non-increasing order of their scores. The corresponding Term will be the letter which specifies the level;
  • Type being 2 means to output the total number of testees together with their total scores in a given site. The corresponding Term will then be the site number;
  • Type being 3 means to output the total number of testees of every site for a given test date. The corresponding Term will then be the date, given in the same format as in the registration card.

Output Specification:

For each query, first print in a line Case #: input, where # is the index of the query case, starting from 1; and input is a copy of the corresponding input query. Then output as requested:

  • for a type 1 query, the output format is the same as in input, that is, CardNumber Score. If there is a tie of the scores, output in increasing alphabetical order of their card numbers (uniqueness of the card numbers is guaranteed);
  • for a type 2 query, output in the format Nt Ns where Nt is the total number of testees and Ns is their total score;
  • for a type 3 query, output in the format Site Nt where Site is the site number and Nt is the total number of testees at Site. The output must be in non-increasing order of Nt's, or in increasing order of site numbers if there is a tie of Nt.

If the result of a query is empty, simply print NA.

Sample Input:

8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999

Sample Output:

Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA

 題意:按照題目給的三個格式,進行查詢輸出

思路:模擬題,

考點:1.模擬處理(邏輯思維)2.hash對映 3.字串處理

 坑點: 1.邏輯清晰,字串處理仔細即可

             2.注意不要用cout輸出,避免後面兩個測試點執行超時,以後我再也不用cout了做題了(開個玩笑,注意資料量即可) !!!!

(但這道題我硬是花了2.30左右沒寫出來,開始直接想把一個card分為5 部分儲存,然後就寫啊寫啊,就這麼寫了半個點過去了,後來發現字串處理+map/hash就可以做了,可是字串處理時,腦袋迷糊了,不會用substr(),就ASCII硬湊。。。涼涼)

補充:這題我儲存時應該比較繁雜,應該有更簡單資料結構設計求解。

#include <bits/stdc++.h>
using namespace std;
struct Node1{
    string s;
    int sc;
};
struct Node3{
    int site;
    int cnt;
};

bool cmp3(Node3 a,Node3 b){
    if(a.cnt!=b.cnt)return a.cnt>b.cnt;
    else return a.site<b.site;
}

bool cmp1(Node1 a,Node1 b){
    if(a.sc!=b.sc)return a.sc>b.sc;
    else return a.s<b.s;
}
map<char,vector<pair<string,int>>> type1;
map<int,pair<int,int>>type2;
map<int,vector<int>>type3;

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        string t_str;
        int t_score;
        cin>>t_str>>t_score;
        type1[t_str[0]].push_back(pair<string,int>(t_str,t_score));
        type2[stoi(t_str.substr(1,3))].first++;
        type2[stoi(t_str.substr(1,3))].second+=t_score;
        type3[stoi(t_str.substr(4,6))].push_back(stoi(t_str.substr(1,3)));
    }
    for(int i=0;i<m;i++){
        int type;
        string term;
        cin>>type>>term;
        printf("Case %d: %d %s\n",i+1,type,term.c_str());
        //cout<<"Case "<<i+1<<": "<<type<<" "<<term<<endl;
        if(type==1){
            vector<Node1> ans;
            if(type1.find(term[0])==type1.end()){
                printf("NA\n");
                continue;
            }
            for(int j=0;j<type1[term[0]].size();j++){
                ans.push_back(Node1{type1[term[0]][j].first,type1[term[0]][j].second});
            }
            sort(ans.begin(),ans.end(),cmp1);
            for(int j=0;j<ans.size();j++){
                printf("%s %d\n",ans[j].s.c_str(),ans[j].sc);
                //cout<<ans[j].s<<" "<<ans[j].sc<<endl;
            }
            continue;
        }
        if(type==2){
            if(type2.find(stoi(term))==type2.end()){
                printf("NA\n");
                //cout<<"NA"<<endl;
                continue;
            }
            printf("%d %d\n",type2[stoi(term)].first,type2[stoi(term)].second);
           // cout<<type2[stoi(term)].first<<" "<<type2[stoi(term)].second<<endl;
        }
        if(type==3){
            if(type3.find(stoi(term))==type3.end()){
                printf("NA\n");
                //cout<<"NA"<<endl;
                continue;
            }
            vector<Node3> ans;
            int hashTable[1000]={0};
            for(int i=0;i<type3[stoi(term)].size();i++){
                hashTable[type3[stoi(term)][i]]++;
            }
            for(int i=101;i<1000;i++){
                if(hashTable[i]!=0){
                    ans.push_back(Node3{i,hashTable[i]});
                }
            }
            sort(ans.begin(),ans.end(),cmp3);
            for(int i=0;i<ans.size();i++){
                printf("%d %d\n",ans[i].site,ans[i].cnt);
                //cout<<ans[i].site<<" "<<ans[i].cnt<<endl;
            }
            continue;
        }
    }

    return 0;
}

1154 Vertex Coloring (25 分)

proper vertex coloring is a labeling of the graph's vertices with colors such that no two vertices sharing the same edge have the same color. A coloring using at most k colors is called a (proper) k-coloring.

Now you are supposed to tell if a given coloring is a proper k-coloring.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 10​4​​), being the total numbers of vertices and edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N−1) of the two ends of the edge.

After the graph, a positive integer K (≤ 100) is given, which is the number of colorings you are supposed to check. Then K lines follow, each contains N colors which are represented by non-negative integers in the range of int. The i-th color is the color of the i-th vertex.

Output Specification:

For each coloring, print in a line k-coloring if it is a proper k-coloring for some positive k, or No if not.

Sample Input:

10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
4
0 1 0 1 4 1 0 1 3 0
0 1 0 1 4 1 0 1 0 0
8 1 0 1 4 1 0 5 3 0
1 2 3 4 5 6 7 8 8 9

Sample Output:

4-coloring
No
6-coloring
No

題意:任意相連兩點,頂點顏色不可相同,如果有即No,否則判斷用了多少種顏色標註

思路:鄰接矩陣儲存相連的頂點,另闢陣列儲存頂點顏色,暴力求解~~判斷想連兩點的顏色是否相同,如果相同則flag=false,跳出,最後根據flag輸出結果; 

考點: 1.圖的儲存及遍歷(這裡在遍歷中判斷了點權的性質)2.set

坑點:~~貌似沒 回來看這題開始讀題沒太懂花好久時間,後來放了放再想理解題意,然後編碼很快就做出來了,編碼時間可能沒過20分鐘;

#include <bits/stdc++.h>

using namespace std;
const int maxn=10010;
vector<int>Adj[maxn];

int main()
{
    int n,m,k,v1,v2;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>v1>>v2;
        Adj[v1].push_back(v2);
        Adj[v2].push_back(v1);
    }
    cin>>k;
    vector<int> vcolor;
    vcolor.resize(n);
    set<int> Set;
    for(int i=0;i<k;i++){
          Set.clear();
        for(int j=0;j<n;j++){
            int temp;
            cin>>temp;
            Set.insert(temp);
            vcolor[j]=temp;
        }
        bool flag=true;
        for(int j=0;j<n;j++){
            for(int t=0;t<Adj[j].size();t++){
                if(vcolor[j]==vcolor[Adj[j][t]]){
                    flag=false;
                    break;
                }
                if(flag==false)break;
            }
        }
        if(flag==true){
            printf("%d-coloring",Set.size());
        }else printf("No");
        if(i<k-1)printf("\n");
    }
    return 0;
}

 

 

1155 Heap Paths (30 分)

In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is either greater than or equal to (in a max heap) or less than or equal to (in a min heap) the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree. (Quoted from Wikipedia at https://en.wikipedia.org/wiki/Heap_(data_structure))

One thing for sure is that all the keys along any path from the root to a leaf in a max/min heap must be in non-increasing/non-decreasing order.

Your job is to check every path in a given complete binary tree, in order to tell if it is a heap or not.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (1<N≤1,000), the number of keys in the tree. Then the next line contains N distinct integer keys (all in the range of int), which gives the level order traversal sequence of a complete binary tree.

Output Specification:

For each given tree, first print all the paths from the root to the leaves. Each path occupies a line, with all the numbers separated by a space, and no extra space at the beginning or the end of the line. The paths must be printed in the following order: for each node in the tree, all the paths in its right subtree must be printed before those in its left subtree.

Finally print in a line Max Heap if it is a max heap, or Min Heap for a min heap, or Not Heap if it is not a heap at all.

Sample Input 1:

8
98 72 86 60 65 12 23 50

Sample Output 1:

98 86 23
98 86 12
98 72 65
98 72 60 50
Max Heap

Sample Input 2:

8
8 38 25 58 52 82 70 60

Sample Output 2:

8 25 70
8 25 82
8 38 52
8 38 58 60
Min Heap

Sample Input 3:

8
10 28 15 12 34 9 8 56

Sample Output 3:

10 15 8
10 15 9
10 28 34
10 28 12 56
Not Heap

 題意:heap的判斷,根到葉子結點路徑的輸出

思路 :因為是完成二叉樹,所有采用開陣列儲存結點,開個二維陣列儲存所有路徑,一維陣列儲存當前路徑。然後DFS遍歷訪問。

考點 1.heap 2.樹的遍歷(這裡我用DFS)

坑點 :主要就是考察對以上知識點的熟練程度以及結點只有兩個時的特判情況~ (這題和上上次考試heap可以說同出一轍;)我直接將上次練習考試時的程式碼判斷部分的程式碼拿來直接用了,再次考試時注意注意熟練程度!!!,這裡書寫DFS時又迷糊了半小時,,,,

這裡判斷的程式碼應該是較為繁瑣,應該還有更簡單方法,參考網上大神的吧。有空我再來想想,二刷或三刷不能避免了 這次就刷一遍上考場就真的,,,,,。

#include <bits/stdc++.h>

using namespace std;
vector<int> Tree;
vector<vector<int>>ans;

vector<int>temp;
int n;

int judge(int n){
    int isMax=0;
    bool isFirst=true;
    queue<int> Q;
    Q.push(1);
    while(!Q.empty()){
        int flagl=isMax,flagr=isMax;//判斷當前結點和子結點的關係
        int fp=Q.front();
        Q.pop();
        int left=fp*2,right=fp*2+1;
        if(left<=n){
            Q.push(left);
            int temp=Tree[fp]-Tree[left];
            if(temp>0)flagl=1;
            if(temp<0)flagl=-1;
        }
        if(right<=n){
            Q.push(right);
            int temp=Tree[fp]-Tree[right];
            if(temp>0)flagr=1;
            if(temp<0) flagr=-1;
        }
        if(flagl!=flagr){
            isMax=0;
            return isMax;
        }
        if(flagl==flagr&&isFirst){
            isMax=flagl;
            isFirst=false;
        }
        if(flagl==flagr&&isFirst==false){
            if(flagl==flagr&&flagl!=isMax){
                isMax=0;
                return isMax;
            }
        }
    }
    return isMax;
}

void DFS(int x){
    if(x>n){
        return;
    }
    temp.push_back(Tree[x]);
    if(2*x+1>n&&2*x>n){
        ans.push_back(temp);
    }
    if(2*x+1<=n)DFS(2*x+1);
    if(2*x<=n)DFS(2*x);
    temp.pop_back();

}

int main()
{
    scanf("%d",&n);
    Tree.resize(n+1);
    for(int i=1;i<=n;i++){
        int t;
        cin>>t;
        Tree[i]=t;
    }
   DFS(1);
   for(int i=0;i<ans.size();i++){
        for(int j=0;j<ans[i].size();j++){
            cout<<ans[i][j];
            if(j<ans[i].size()-1)cout<<" ";
            else cout<<endl;
        }
   }
   int flag=0;
   for(int i=0;i<ans.size();i++){
        for(int j=0;j<ans[i].size();j++){

        }
   }
    if(n==2){
            if(Tree[1]>Tree[2])printf("Max Heap");
            else printf("Min Heap");
            return 0;
        }
    int isMax=judge(n);
    if(isMax==1)printf("Max Heap");
    if(isMax==0)printf("Not Heap");
    if(isMax==-1)printf("Min Heap");
    return 0;
}

總結:

三個點做了兩道題,一道還有一個測試點沒過19分,第二道,第三個型別查詢出錯除錯未果零分

咱不虧畢竟今天在考場外花了六個多點才完成這篇博文,不哭不哭。路走著總會有道友的。

知道為什麼錯了嗎,知道;知道考了哪裡嗎,好像大概就是這這這;應該用什麼方法,這把這把,寫寫寫,我去不對,不對;

英文閱讀平時得注意!!!第二題題目讀了可能就10分鐘,第三,四題考場上看都沒看,,,。回來看第三題時,也卡了半天

注意提升的:

1.閱讀英文不慌不慌,咱慢慢來!!!2. 訓練時切記解題速度以及定時練套題(大神總是會在1.30左右做完,膜拜膜拜)

3.程式語言的熟練應用(這次在substr上吃了大虧,第二題就直接洗白我了,我用substr()時不知道哪抽筋了mmp HH)

4.常見資料結構演算法的熟練 熟練 再熟練

5.環境的熟悉(考場時codeblock得自己設定除錯的路徑 gdb.exe,明明就一份種的事情,我當時就為什麼不選擇試試2333)

6.養成良好的程式設計習慣,注意邏輯嚴謹的訓練

7.one step one step 好好幹!