PAT(甲级)2019年春季考试 解题报告

这次刚做30分钟过了两题就被打断了...然后再看就没时间了,时光机白买了,而且还没改完....不过这次的第三题第四题确实麻烦一些

7-1

Sexy Primes

Sexy primes are pairs of primes of the form (p, p+6), so-named since "sex" is the Latin word for "six". (Quoted from http://mathworld.wolfram.com/SexyPrimes.html)

Now given an integer, you are supposed to tell if it is a sexy prime.

Input Specification:

Each input file contains one test case. Each case gives a positive integer N (≤10​8​​).

Output Specification:

For each case, print in a line Yes if N is a sexy prime, then print in the next line the other sexy prime paired with N (if the answer is not unique, output the smaller number). Or if N is not a sexy prime, print No instead, then print in the next line the smallest sexy prime which is larger than N.

Sample Input 1:

47

Sample Output 1:

Yes
41

Sample Input 2:

21

Sample Output 2:

No
23

分析:

Sexy primes are pairs of primes of the form (p, p+6), so-named since "sex" is the Latin word for "six".

性感素数是一对素数的形式(p,p+6),因此得名,因为“性”是拉丁语中的“六”。

坑点:

(p,p+6) 注意是双向的,即(p,p-6) (p,p+6),不过这个也容易被注意到

代码: 

// Sexy primes are pairs of primes of the form (p, p+6), so-named since "sex" is the Latin word for "six". 
#include
using namespace std;
bool isPrime(int n){
    if(n<2) return false;
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0) return false;
    }
    return true;
}
int main(){
    int n;
    cin>>n;
    if(isPrime(n)&&isPrime(n-6)){
        cout<<"Yes"<

 

7-2

Anniversary

Zhejiang University is about to celebrate her 122th anniversary in 2019. To prepare for the celebration, the alumni association (校友会) has gathered the ID's of all her alumni. Now your job is to write a program to count the number of alumni among all the people who come to the celebration.

Input Specification:

Each input file contains one test case. For each case, the first part is about the information of all the alumni. Given in the first line is a positive integer N (≤10​5​​). Then N lines follow, each contains an ID number of an alumnus. An ID number is a string of 18 digits or the letter X. It is guaranteed that all the ID's are distinct.

The next part gives the information of all the people who come to the celebration. Again given in the first line is a positive integer M (≤10​5​​). Then M lines follow, each contains an ID number of a guest. It is guaranteed that all the ID's are distinct.

Output Specification:

First print in a line the number of alumni among all the people who come to the celebration. Then in the second line, print the ID of the oldest alumnus -- notice that the 7th - 14th digits of the ID gives one's birth date. If no alumnus comes, output the ID of the oldest guest instead. It is guaranteed that such an alumnus or guest is unique.

Sample Input:

5
372928196906118710
610481197806202213
440684198612150417
13072819571002001X
150702193604190912
6
530125197901260019
150702193604190912
220221196701020034
610481197806202213
440684198612150417
370205198709275042

Sample Output:

3
150702193604190912

分析:

这个题也是巨简单~ 用map看string在不在,最老的用substr把生日截取直接比大小就行

代码:

//  notice that the 7th - 14th digits of the ID gives one's birth date. If no alumnus comes, output the ID of the oldest guest instead. 
#include
using namespace std;
int cnt=0;
map mp;
int main(){
    int n,m;
    cin>>n;
    string o1="99999999",o2="99999999";
    string a1,a2;
    while(n--){
        string a,b;
        cin>>a;
        mp[a]=1;
        b=a.substr(7,8);
        if(b>m;
    while(m--){
        string a,b;
        cin>>a;
        if(mp[a]==1) cnt++;
        b=a.substr(7,8);
        if(b

7-3

Telefraud Detection

Telefraud(电信诈骗) remains a common and persistent problem in our society. In some cases, unsuspecting victims lose their entire life savings. To stop this crime, you are supposed to write a program to detect those suspects from a huge amount of phone call records.

A person must be detected as a suspect if he/she makes more than K short phone calls to different people everyday, but no more than 20% of these people would call back. And more, if two suspects are calling each other, we say they might belong to the same gang. A makes a short phone call to B means that the total duration of the calls from A to B is no more than 5 minutes.

Input Specification:

Each input file contains one test case. For each case, the first line gives 3 positive integers K (≤500, the threshold(阈值) of the amount of short phone calls), N (≤10​3​​, the number of different phone numbers), and M (≤10​5​​, the number of phone call records). Then M lines of one day's records are given, each in the format:

caller receiver duration

where caller and receiver are numbered from 1 to N, and duration is no more than 1440 minutes in a day.

Output Specification:

Print in each line all the detected suspects in a gang, in ascending order of their numbers. The gangs are printed in ascending order of their first members. The numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

If no one is detected, output None instead.

Sample Input 1:

5 15 31
1 4 2
1 5 2
1 5 4
1 7 5
1 8 3
1 9 1
1 6 5
1 15 2
1 15 5
3 2 2
3 5 15
3 13 1
3 12 1
3 14 1
3 10 2
3 11 5
5 2 1
5 3 10
5 1 1
5 7 2
5 6 1
5 13 4
5 15 1
11 10 5
12 14 1
6 1 1
6 9 2
6 10 5
6 11 2
6 12 1
6 13 1

Sample Output 1:

3 5
6

Note: In sample 1, although 1 had 9 records, but there were 7 distinct receivers, among which 5 and 15 both had conversations lasted more than 5 minutes in total. Hence 1 had made 5 short phone calls and didn't exceed the threshold 5, and therefore is not a suspect.

Sample Input 2:

5 7 8
1 2 1
1 3 1
1 4 1
1 5 1
1 6 1
1 7 1
2 1 1
3 1 1

Sample Output 2:

None

分析:

首先按它说的规则把嫌疑人都push_back到vector v;

然后让用并查集让他们拉帮结派

最后用一个map> p;把father和对应的一群gang输出即可。

这里除了并查集我看到还有别的做法~

坑点:

没时间了,数据有点多懒得看,....没意识到电话是随便打的,通话时间累加

然后又把输出顺序看错了- -..... 我以为在说先在总数排序再按首数字大小,还思考怎么第三题会这样(所以得了15分)

代码:

#include
using namespace std;
#define MAX 1005
int g[MAX][MAX];
int k,m,n; 
int father[MAX];
int findFather(int a){
    int x=a;
    while(a!=father[a]) a=father[a];
    while(x!=father[x]){
        int z=x;
        x=father[x];
        father[x]=a;
    }
    return a;
}
void Union(int a,int b){
    int fa=findFather(a);
    int fb=findFather(b);
    if(fa>fb) father[fa]=fb;
    else father[fb]=fa;
}
int main(){
	scanf("%d %d %d",&k,&n,&m);
	fill(g[0],g[0]+MAX*MAX,0);
	for(int i=0;i v;
    for(int i=1;i<=n;i++){
        int shortx=0;
        int huibo=0;
        for(int j=1;j<=n;j++){
            if(g[i][j]!=0&&g[i][j]<=5){
                shortx++;
                if(g[j][i]!=0) huibo++;
            }
        }
        if(shortx>k&&(double)huibo<=(double)shortx*0.2){
            v.push_back(i);
        }
    }
    if(v.size()==0){
    	cout<<"None";return 0;
    }
    for(int i=0;i> p;
    for(int i=0;i c=mp.second;
        for(int j=0;j

7-4

Structure of a Binary Tree

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.

Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:

  • A is the root
  • A and B are siblings
  • A is the parent of B
  • A is the left child of B
  • A is the right child of B
  • A and B are on the same level
  • It is a full tree

Note:

  • Two nodes are on the same level, means that they have the same depth.
  • A full binary tree is a tree in which every node other than the leaves has two children.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than 10​3​​ and are separated by a space.

Then another positive integer M (≤30) is given, followed by M lines of statements. It is guaranteed that both A and B in the statements are in the tree.

Output Specification:

For each statement, print in a line Yes if it is correct, or No if not.

Sample Input:

9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree

Sample Output:

Yes
No
Yes
No
Yes
Yes
Yes

分析:

1、根据中序序列和后序序列建树

2、补充信息,信息包括 所在层、parent、full  这些补充信息都可以在建树时加入,然后用map把数值对应结点 积累经验

3、处理字符串,要熟悉简单的处理方法,不然会觉得很麻烦。积累经验

代码:

#include
using namespace std;
struct node{
	node *left,*right,*parent;
	int data;
	node(int d=0):left(NULL),right(NULL),parent(NULL),data(d){
	}
};
int post[32],inn[32];
map level;//数值对应层 
map mp;//数值对应结点 
bool isfull=true;
node* build(int li,int ri,int lp,int rp,int depth){
	if(li>ri) return NULL;
	int root=post[rp],j=li;
	while(inn[j]!=root) j++;
	node* r = new node(root);
	level[root]=depth;
	r->left=build(li,j-1,lp,lp+j-1-li,depth+1);
	r->right=build(j+1,ri,rp+j-ri,rp-1,depth+1);
	if(r->left) r->left->parent=r;
	if(r->right) r->right->parent=r;
	if((!r->left && r->right) || (r->left && !r->right)) isfull = false;
    mp[root] = r;
    return r;
}
void solve(string &s,node *r){
	int a,b;
	if(s.find("root")!=string::npos){
		sscanf(s.c_str(),"%d is the root",&a);
		r->data==a? printf("Yes\n"):printf("No\n");
	}
	else if(s.find("siblings") != string::npos){
        sscanf(s.c_str(), "%d and %d are siblings", &a, &b);
        node *p = mp[a], *q = mp[b];
        p->parent == q->parent ? printf("Yes\n") : printf("No\n");
    }
    else if(s.find("parent") != string::npos){
        sscanf(s.c_str(), "%d is the parent of %d", &a, &b);
        node *p = mp[a], *q = mp[b];
        p == q->parent ? printf("Yes\n") : printf("No\n");
    }
    else if(s.find("left child") != string::npos){
        sscanf(s.c_str(), "%d is the left child of %d", &a, &b);
        node *p = mp[a], *q = mp[b];
        p == q->left ? printf("Yes\n") : printf("No\n");
    }
    else if(s.find("right child") != string::npos){
        sscanf(s.c_str(), "%d is the right child of %d", &a, &b);
        node *p = mp[a], *q = mp[b];
        p == q->right ? printf("Yes\n") : printf("No\n");
    }
    else if(s.find("level") != string::npos){
        sscanf(s.c_str(), "%d and %d are on the same level", &a, &b);
        level[a] == level[b] ? printf("Yes\n") : printf("No\n");
    }
    else if(s.find("full") != string::npos){
        isfull ? printf("Yes\n") : printf("No\n");
    }
} 
int main(){
	int n,m;
	cin>>n;
	for(int i=0;i>post[i];
	for(int i=0;i>inn[i];
	node* root=build(0,n-1,0,n-1,1);
	cin>>m;
	getchar();
	while(m--){
		string s;
		getline(cin,s);
		solve(s,root);
	}
	return 0;
	
} 

总结:

本次的难度是50满分/1500人

总的来说难度正常吧~

1、好好读题,如果在考试的时候不必看排行榜(至少前2个小时

2、树有关的题要积累经验,争取用简洁的方法就能完成

 

你可能感兴趣的:(PAT甲级)