PAT甲级2019秋季考试题解
7-1 Forever
判断区间内的符合条件的数并输出
直接暴力加排序会有两个点tle,加点剪枝卡测试点就ac,具体看代码吧,近几年的a题都是这个风格~
#include<bits/stdc++.h> using namespace std; const int maxn=1014; struct node { int data; int n; }; int gcd (int a,int b) { return b==0?a:gcd(b,a%b); } int isprime (int n) { if (n<=2) return 0; if (n%2==0) return 0; for (int i=3;i*i<=n;i++) if (n%i==0) return 0; return 1; } int digitsum (int n) { string s=to_string(n); int ans=0; for (int i=0;i<s.length();i++) ans+=s[i]-'0'; return ans; } bool cmp (node a,node b) { if (a.n!=b.n) return a.n<b.n; else return a.data<b.data; } int main () { int N,K,M; scanf ("%d",&N); for (int i=0;i<N;i++) { scanf ("%d %d",&K,&M); int flag=0; printf ("Case %d\n",i+1); //if (M>=9*K) { //printf ("No Solution\n"); //continue; // } vector<node> vi; for (int j=pow(10,K-1)+pow(10,K-2)-1;j<pow(10,K);j+=100) { //if (j%10!=9) continue; if (digitsum(j)!=M) continue; int n=digitsum(j+1); if (isprime(gcd(M,n))) { //flag++; vi.push_back({j,digitsum(j+1)}); //printf ("%d %d\n",n,j); } } if (vi.size()==0) printf ("No Solution\n"); else { sort (vi.begin(),vi.end(),cmp); for (int j=0;j<vi.size();j++) { printf ("%d %d\n",vi[j].n,vi[j].data); } } } return 0; }
7-2 Merging Linked Lists
链表重排,用结构体实现静态链表并输出,老模板题了~
#include<bits/stdc++.h> using namespace std; const int maxn=1014; struct node { int address; int data; int next; }Node[100010]; int main () { int head1,head2,n; scanf ("%d %d %d",&head1,&head2,&n); int address,data,next; for (int i=0;i<n;i++) { scanf ("%d %d %d",&address,&data,&next); Node[address].address=address; Node[address].data=data; Node[address].next=next; } vector<node> l1,l2; while (head1!=-1) { l1.push_back(Node[head1]); head1=Node[head1].next; } while (head2!=-1) { l2.push_back(Node[head2]); head2=Node[head2].next; } int len1=l1.size(),len2=l2.size(),cnt=0; if (len1>len2) { printf ("%05d %d ",l1[0].address,l1[0].data); for (int i=1;i<len1;i++) { printf ("%05d\n%05d %d ",l1[i].address,l1[i].address,l1[i].data); if ((i+1)%2==0&&cnt<len2) { printf ("%05d\n%05d %d ",l2[len2-1-cnt].address,l2[len2-1-cnt].address,l2[len2-1-cnt].data); cnt++; } if (i==len1-1) { printf ("-1"); } } } else { printf ("%05d %d ",l2[0].address,l2[0].data); for (int i=1;i<len2;i++) { printf ("%05d\n%05d %d ",l2[i].address,l2[i].address,l2[i].data); if ((i+1)%2==0&&cnt<len1) { printf ("%05d\n%05d %d ",l1[len1-1-cnt].address,l1[len1-1-cnt].address,l1[len1-1-cnt].data); cnt++; } if (i==len2-1) { printf ("-1"); } } } return 0; }
7-3 Postfix Expression
对表达式树进行dfs,对着样例瞎搞搞就ac,具体看代码~
#include <iostream> #include <string> using namespace std; struct node { string s; int lChild, rChild, parent = -1; }; node nodes[30]; void dfs(int root) { if ((nodes[root].lChild == -1 || nodes[root].rChild == -1) && nodes[root].lChild != nodes[root].rChild) { cout << "(" << nodes[root].s; if (nodes[root].lChild != -1) dfs(nodes[root].lChild); if (nodes[root].rChild != -1) dfs(nodes[root].rChild); cout << ")"; } else if (nodes[root].lChild != -1) { cout << "("; dfs(nodes[root].lChild); dfs(nodes[root].rChild); cout << nodes[root].s << ")"; } else { cout << "(" << nodes[root].s << ")"; } } int main() { int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> nodes[i].s >> nodes[i].lChild >> nodes[i].rChild; nodes[nodes[i].lChild].parent = i; nodes[nodes[i].rChild].parent = i; } int root = 1; while (nodes[root].parent != -1) root = nodes[root].parent; dfs(root); }
7-4 Dijkstra Sequence
用floyd算法算出起点到所有结点的最短距离,再判断给定序列里的点到起点的最短距离是否是升序~
#include<bits/stdc++.h> using namespace std; const int maxn=1014; const int inf=1e9; int d[maxn][maxn]; int mind[maxn]; int N,M; void floyd () { for (int k=1;k<=N;k++) for (int i=1;i<=N;i++) for (int j=1;j<=N;j++) if (i!=j) { d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } } int main () { scanf ("%d %d",&N,&M); for (int i=1;i<=N;i++) for (int j=1;j<=N;j++) d[i][j]=inf; int u,v; for (int i=0;i<M;i++) { scanf ("%d %d",&u,&v); scanf ("%d",&d[u][v]); d[v][u]=d[u][v]; } floyd (); int k; scanf ("%d",&k); int a[maxn]; for (int i=0;i<k;i++) { scanf ("%d",&a[0]); int flag=0; for (int j=1;j<N;j++) { scanf ("%d",&a[j]); } for (int j=1;j<N-1;j++) { if (d[a[0]][a[j]]>d[a[0]][a[j+1]]) flag++; } if (flag==0) printf ("Yes\n"); else printf ("No\n"); } return 0; }