PAT A1152-A1155题解报告(即PAT 2018.12.9冬季甲级考试题)

版权声明:敲一敲看一看 https://blog.csdn.net/idealhunting/article/details/84942739

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 好好干!

猜你喜欢

转载自blog.csdn.net/idealhunting/article/details/84942739
今日推荐