PAT-2020年春季考试_2020.07.22_线上模拟_甲级1087-1090_心得+题解
题外话:PAT甲级满分可以去姥姥公司^_^,955高性价比
投递简历连接https://www.pat-edu.com/jia-ru-wo-men.html
--------------------------------------------------------
级别:甲级
时间2020年7月22日,下午13:30-16:30,线上模拟,双机位摄像头,需要提前一小时测试比赛环境、调整机器。
本次模拟使用题集:PTA甲级1087、1088、1089、1090
监考客户端下载:https://pintia.cn/problem-sets?tab=0
1087(第四题):
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int maxn=250; string s[maxn],start;//,res; int val[maxn],G[maxn][maxn]; bool vst[maxn]; map<string,int>mp; map<int,string>mp2; int num[1000000],cost=inf,happy,avehappy,happynum,_end; int n,k; int a[maxn],tmp[maxn]; void dfs(int cur,int _cost,int _happy,int _happynum) { tmp[_happynum]=cur; //cout<<_happynum<<" "<<cur<<endl; if(cur==_end) { //cout<<cur<<" "<<_cost<<" "<<_happy<<" "<<_happynum<<endl; //for(int i=0;i<=_happynum;i++)cout<<tmp[i]<<" "; //cout<<endl; num[_cost]++; if(_cost<cost) { cost=_cost; happy=_happy; happynum=_happynum; for(int i=0;i<=_happynum;i++)a[i]=tmp[i]; } else if(_cost==cost) { if(_happy>happy) { cost=_cost; happy=_happy; happynum=_happynum; for(int i=0;i<=_happynum;i++)a[i]=tmp[i]; } else if(_happy==happy&&_happynum<happynum) { cost=_cost; happy=_happy; happynum=_happynum; for(int i=0;i<=_happynum;i++)a[i]=tmp[i]; } } return; } for(int i=0;i<n;i++) { if(G[cur][i]!=-1&&!vst[i]) { vst[i]=1; dfs(i,_cost+G[cur][i],_happy+val[i],_happynum+1); vst[i]=0; } } } int main() { cin>>n>>k>>start; mp[start]=0; mp2[0]=start; for(int i=1;i<n;i++) { cin>>s[i]>>val[i]; mp[s[i]]=i; mp2[i]=s[i]; if(s[i]=="ROM")_end=i; } memset(G,-1,sizeof G); for(int i=0;i<k;i++) { string s1,s2; int cst; cin>>s1>>s2>>cst; G[mp[s1]][mp[s2]]=G[mp[s2]][mp[s1]]=cst; } vst[0]=1; dfs(0,0,0,0); double avehappy=happy/happynum; cout<<num[cost]<<" "<<cost<<" "<<happy<<" "<<avehappy<<endl; for(int i=0;i<happynum;i++) { cout<<mp2[a[i]]<<"->"; } cout<<"ROM"<<endl; //cout<<res<<endl; return 0; }
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f; const int maxn=250; string s[maxn],start,res; int val[maxn],G[maxn][maxn]; bool vst[maxn]; map<string,int>mp; map<int,string>mp2; int num[1000000],cost=inf,happy,avehappy,happynum,_end; int n,k; void dfs(int cur,int _cost,int _happy,int _happynum,string s) { if(cur==_end) { //cout<<cur<<" "<<_cost<<" "<<_happy<<" "<<_happynum<<" "<<s<<endl; num[_cost]++; if(_cost<cost) { cost=_cost; happy=_happy; happynum=_happynum; res=s; } else if(_cost==cost) { if(_happy>happy) { cost=_cost; happy=_happy; happynum=_happynum; res=s; } else if(_happy==happy&&_happynum<happynum) { cost=_cost; happy=_happy; happynum=_happynum; res=s; } } return; } for(int i=0;i<n;i++) { if(G[cur][i]!=-1&&!vst[i]) { vst[i]=1; dfs(i,_cost+G[cur][i],_happy+val[i],_happynum+1,s+"->"+mp2[i]); vst[i]=0; } } } int main() { cin>>n>>k>>start; mp[start]=0; mp2[0]=start; for(int i=1;i<n;i++) { cin>>s[i]>>val[i]; mp[s[i]]=i; mp2[i]=s[i]; if(s[i]=="ROM")_end=i; } memset(G,-1,sizeof G); for(int i=0;i<k;i++) { string s1,s2; int cst; cin>>s1>>s2>>cst; G[mp[s1]][mp[s2]]=G[mp[s2]][mp[s1]]=cst; } vst[0]=1; dfs(0,0,0,0,mp2[0]); avehappy=happy/happynum; cout<<num[cost]<<" "<<cost<<" "<<happy<<" "<<avehappy<<endl; cout<<res<<endl; return 0; }
1088(第一题):
#include<bits/stdc++.h> using namespace std; void cal(long long a,long long b) { long long ans,a2,b2; if(b==0) { cout<<"Inf"; return; } if(b<0)a=-a,b=-b; if(a==0) { cout<<0; } else if(a>0) { ans=a/b,a2=a%b,b2=b; int tmp=__gcd(a2,b2); a2=a2/tmp; b2=b2/tmp; if(a2==0)cout<<ans; else if(ans==0)cout<<a2<<"/"<<b2; else cout<<ans<<" "<<a2<<"/"<<b2; } else { a=-a; ans=a/b,a2=a%b,b2=b; int tmp=__gcd(a2,b2); a2=a2/tmp; b2=b2/tmp; cout<<"(-"; if(a2==0)cout<<ans; else if(ans==0)cout<<a2<<"/"<<b2; else cout<<ans<<" "<<a2<<"/"<<b2; cout<<")"; } } void sol(long long a,long long b,long long c,long long d,char ch) { if(ch=='+') { cal(a*d+b*c,b*d); } else if(ch=='-') { cal(a*d-b*c,b*d); } else if(ch=='*') { cal(a*c,b*d); } else { cal(a*d,b*c); } } int main() { long long a,b,c,d; scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d); //cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl; cal(a,b);cout<<" + ";cal(c,d);cout<<" = ";sol(a,b,c,d,'+');cout<<endl; cal(a,b);cout<<" - ";cal(c,d);cout<<" = ";sol(a,b,c,d,'-');cout<<endl; cal(a,b);cout<<" * ";cal(c,d);cout<<" = ";sol(a,b,c,d,'*');cout<<endl; cal(a,b);cout<<" / ";cal(c,d);cout<<" = ";sol(a,b,c,d,'/');cout<<endl; return 0; }
1089(第二题):
#include<bits/stdc++.h> using namespace std; const int maxn=200; int a[maxn],b[maxn]; int tmp[maxn],n; bool cmp() { /* for(int i=0;i<n;i++) { cout<<tmp[i]<<" "; } cout<<endl; */ for(int i=0;i<n;i++) { if(tmp[i]!=b[i])return false; } return true; } void Insertion() { for(int i=0;i<n;i++)tmp[i]=a[i]; for(int i=2;i<=n;i++)//如果i从1开始,Merge函数要运行在Insertion函数前 { sort(tmp,tmp+i); if(cmp()) { int last=min(i+1,n); sort(tmp,tmp+last); cout<<"Insertion Sort"<<endl; for(int j=0;j<n-1;j++)cout<<tmp[j]<<" "; cout<<tmp[n-1]<<endl; exit(0); } } } void Merge() { for(int i=0;i<n;i++)tmp[i]=a[i]; for(int i=1;;i*=2) { for(int j=0;j<n;j+=i) { int l=j,r=min(j+i,n); sort(tmp+l,tmp+r); //cout<<l<<" "<<r-1<<endl; //merge(j,j+i); } if(cmp()) { cout<<"Merge Sort"<<endl; i*=2; for(int j=0;j<n;j+=i) { int l=j,r=min(j+i,n); sort(tmp+l,tmp+r); } for(int j=0;j<n-1;j++)cout<<tmp[j]<<" "; cout<<tmp[n-1]<<endl; exit(0); } if(i>n)break; } } int main() { cin>>n; for(int i=0;i<n;i++)cin>>a[i]; for(int i=0;i<n;i++)cin>>b[i]; Insertion(); Merge(); return 0; }
1090(第三题):
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int a[maxn],ans=0,b[maxn]; vector<int> v[maxn]; void dfs(int cur,int len) { int size=v[cur].size(); if(size==0) { ans=max(ans,len); b[len]++; return; } for(int i=0;i<size;i++) { dfs(v[cur][i],len+1); } } int main() { //cout<<1.80*1.01*1.01*1.01<<endl; int n,start=0; long double p,r; cin>>n>>p>>r; for(int i=0;i<n;i++) { cin>>a[i]; if(a[i]==-1)start=i; else v[a[i]].push_back(i); } dfs(start,0); //cout<<ans<<endl; for(int i=0;i<ans;i++) { p=p+p*r*0.01; //cout<<p<<endl; } printf("%.2Lf %d\n",p,b[ans]); //cout<<p<<" "<<b[ans]<<endl; return 0; }
先开第一题,模拟模得头裂了,竟然过了
再看第二题,看得焦头烂额,跳过看别的题
看了两遍第三题,还是没看懂题目,研究了一下样例,貌似懂了一些什么......试了一下然后一发入魂,这个时候还有2hour42min
第三道开的是第四题,本来以为是最短路板子题,后来发现不大行,于是改了一下用了dfs,but最后两个点wa了(23/30),怀疑过avehappy的取整,怀疑过string的长度会不会不够,改完代码之后于事无补,最后发现记录cost最大值的数组开小了,开到1e6之后就过了,这个时候还有1hour22min
最后折回来看第二题,跟着样例学了一发插入排序和归并排序,用sort取巧了,妙得我只想写题解233。不过有个点wa掉了(24/25),盲猜是序列和原序列相同时应该判为Merge sort,写完四题还剩50min
写到第三题的时候看了一眼榜,已经有人AK了,真是巨佬啊......
总体感觉挺愉快~没有被特殊样例卡掉的场次就是好场次
不过考到一半转过头发现后面的机位上显目的qq消息,感觉人都傻了,正式赛一定退qq!
tips:
万能头可以用,所有图论都能开邻接矩阵(不用背邻接表),最短路基本上都可以用dijstra(不用背kruskal),用不到set,基本上map和vector就完事了
刷题请倒序!!!近几年真题题型重复率大,没有时间还要正着刷的都是耍流氓!
自用dijstra板子:
#include <iostream> #include <string.h> using namespace std; const int inf=0x3f3f3f3f; int G[110][110]; int dist[110]; bool vst[110]; int n,m; void dijkstra(int s) { memset(vst,false,sizeof(vst)); memset(dist,0x3f,sizeof(dist)); dist[s]=0; for(int i=0;i<n;i++) { int v,min_d=inf; for(int j=1;j<=n;j++) { if(!vst[j]&&dist[j]<min_d) { min_d=dist[j]; v=j; } } vst[v]=true; for(int j=1;j<=n;j++) { dist[j]=min(dist[j],dist[v]+G[v][j]); } } } int main() { cin>>n>>m; memset(G,0x3f,sizeof(G)); for(int i=0;i<m;i++) { int u,v,len; cin>>u>>v>>len; G[u][v]=G[v][u]=len; } dijkstra(1); for(int i=1;i<=n;i++) { cout<<dist[i]<<" "; } return 0; }
自用并查集板子:
//初始化 void init() { for (int i = 1; i <= n; ++i) { father[i] = i; } } //查找 int get(int x) { if (father[x] == x) { // x 结点就是根结点 return x; } return get(father[x]); // 返回父结点的根结点 } //合并 void merge(int x, int y) { x = get(x); y = get(y); if (x != y) { // 不在同一个集合 father[y] = x; } }
自用前序中序后序转换板子(柳婼版):
自用拓扑排序:
// 使用邻接表存储,若对此数据结构不熟悉,请学习邻接表相关的课程内容 struct edge { int v, next; } e[MAX_M]; int p[MAX_N], eid; int topo() { queue<int> q; for (int i = 1; i <= n; i++) { if (indegree[i] == 0) { // 将所有入度为零的顶点入队 q.push(i); } } while (!q.empty()) { int now = q.front(); cout << "visiting " << now << endl; q.pop(); for (int i = p[now]; i != -1; i = e[i].next) { int v = e[i].v; indegree[v]--; if (indegree[v] == 0) { // 将入度新变成零的顶点入队 q.push(v); } } } }