僅提供個人思路~
題目鏈接:購買考試券 - PAT(甲級)2022年春仿真卷 (pintia.cn)
7-1 Simple Lie Detection (20 分)

/* n道題,閾值為t(分數超過t要輸出!!!) ,k個作答 判題規則: 1.字符串首字母為f,分數-2 2.字符串尾字母為a,分數-1 3.每個相同相同字母的len>5的最長答案段,分數+3 即aaaaaaabbbbbbccccccc,分數為9 4.字母a后為e或者h,分數-4 5.連續遞增字母且len>3,分數+5 */ #include<bits/stdc++.h> using namespace std; int main() { int n,t,k; cin>>n>>t>>k; while(k--) { int res=0; string s; cin>>s; if(s[0]=='f')res-=2; if(s[n-1]=='a')res-=1; //for every longest segment of answeres where the same letter is chosen for consecutive questions, //if the segment length is larger than 5, the score is to +3; //記錄每個字母的最長連續段 int longest_len[200]={0}; for(int i=0;i<n;) { int tmp_len=0; if(i+5<n&&s[i]==s[i+1]&&s[i]==s[i+2]&&s[i]==s[i+3]&&s[i]==s[i+4]&&s[i]==s[i+5]) { i+=5; tmp_len+=5; while(s[i]==s[i+1]&&i+1<n)i++,tmp_len++; } else i++; if(tmp_len>longest_len[s[i-1]])longest_len[s[i-1]]=tmp_len; } //驗證字母的連續段是否與longest_len相符,是則+5 for(int i=0;i<n;) { int tmp_len=0; if(i+5<n&&s[i]==s[i+1]&&s[i]==s[i+2]&&s[i]==s[i+3]&&s[i]==s[i+4]&&s[i]==s[i+5]) { i+=5; tmp_len+=5; while(s[i]==s[i+1]&&i+1<n)i++,tmp_len++; } else i++; if(tmp_len==longest_len[s[i-1]]&&tmp_len)res+=3; } //注意every,測試點1和4會卡 for(int i=0;i+1<n;) { if(s[i]=='a'&&s[i+1]=='e'||s[i]=='a'&&s[i+1]=='h') { res-=4; i+=2; } else i++; } for(int i=0;i<n;) { if(i+3<n&&s[i+1]==s[i]+1&&s[i+2]==s[i]+2&&s[i+3]==s[i]+3) { res+=5; i+=3; while(s[i+1]==s[i]+1&&i+1<n)i++; } else i++; } if(res>t) cout<<res<<"!!!"<<endl; else cout<<res<<endl; } return 0; }
7-2 The First K Largest Numbers (25 分)

#include<bits/stdc++.h> using namespace std; //存1e6會內存超限 int a[100]; bool cmp(int n1,int n2) { return n1>n2; } int main() { int n,k; //cin會超時 scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { //只存前k+1個數並進行排序,很經典的面試題~ //優先隊列、multiSet、map等都可以過這題,try a try int tmp=min(i,k+1); scanf("%d",&a[tmp]); sort(a+1,a+tmp+1,cmp); } for(int i=1;i<=k&&i<=n;i++) { if(i==1)printf("%d",a[i]); else printf(" %d",a[i]); } printf("\n"); return 0; }
7-3 Is It A Binary Search Tree - Again (25 分)

#include<bits/stdc++.h> using namespace std; int n,t[2050]; int a[2050],len=1; //二叉搜索樹的中序變歷為升序 void inOrder(int cur) { if(t[cur]==-1||cur>n)return; inOrder(cur*2); a[len++]=t[cur]; inOrder(cur*2+1); } int main() { cin>>n; for(int i=1;i<=n;i++)cin>>t[i]; inOrder(1); int b[2050]={0}; for(int i=1;i<len;i++)b[i]=a[i]; sort(b+1,b+len); //用b(排序后的a)判斷a是否為升序 bool flag=0; for(int i=1;i<len;i++) { if(b[i]!=a[i])flag=1; } if(!flag)cout<<"YES"<<endl; else cout<<"NO"<<endl; for(int i=1;i<len;i++) { if(i==1)cout<<a[i]; else cout<<" "<<a[i]; } cout<<endl; return 0; }
7-4 The Rescue (30 分)

/* 0 ↑ 3← →1 ↓ 2 ?為人所在位置 有三個距離最遠(4)位置,pick了代碼最small的,給了他0011指令 ?#??? ??X?? ??##? ???#? 起初圖中所有0點都可能有人,所有人執行指令0011后(撞牆不走、到X不走),可能在四個?點處 ?#OO? OOXO? OO##O OO?#O pick了距離最遠(4)的最下面一排的問號,給了他3001指令...... ans的本質是:所以遍布在各個位置的人,聽到這些指令后一一執行,或早或晚最后都能到X這個位置 */ #include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f; char p[105][105]; int len[105][105],vis[105][105]; typedef pair<int, int> PII; map<PII,int> is_hiker; struct node { int x,y; //{x,y}到X的路 string path; }; //先搜出x到所有0的距離 void bfs(int x,int y) { memset(vis,0,sizeof vis); queue<PII>q; q.push({x,y}); vis[x][y]=1; while(!q.empty()) { PII cur=q.front(); q.pop(); for(int i=0;i<4;i++) { int tx=cur.first,ty=cur.second; if(i==0)tx--; if(i==1)ty++; if(i==2)tx++; if(i==3)ty--; if(!vis[tx][ty]&&is_hiker[{tx,ty}]) { vis[tx][ty]=1; len[tx][ty]=len[cur.first][cur.second]+1; q.push({tx,ty}); } } } } //求出{x,y}到x的最small的路,反之求不出來 string cal_path(int x,int y) { memset(vis,0,sizeof vis); queue<struct node> q; struct node start={x,y,""}; q.push(start); vis[x][y]=1; while(true) { struct node cur=q.front(); q.pop(); for(int i=0;i<4;i++) { int tx=cur.x,ty=cur.y; if(i==0)tx--; if(i==1)ty++; if(i==2)tx++; if(i==3)ty--; if(!vis[tx][ty]&&p[tx][ty]!='#') { vis[tx][ty]=1; char ch='0'+i; if(p[tx][ty]=='X')return cur.path+ch; struct node nex={tx,ty,cur.path+ch}; q.push(nex); } } } } //模擬從{tx,ty}按照s指令會走到哪個位置 pair<int, int> walk(int tx,int ty,string s) { for(int i=0;i<s.size();i++) { //遇牆不走 if(s[i]=='0'&&p[tx-1][ty]!='#')tx--; if(s[i]=='1'&&p[tx][ty+1]!='#')ty++; if(s[i]=='2'&&p[tx+1][ty]!='#')tx++; if(s[i]=='3'&&p[tx][ty-1]!='#')ty--; //終點不走 if(p[tx][ty]=='X')return {tx,ty}; } return {tx,ty}; } int main() { int n,m; cin>>n>>m; //把邊圍起來 int x,y; queue<PII> hiker_place; for(int i=0;i<=m+1;i++)p[0][i]='#',p[n+1][i]='#',len[0][i]=len[n+1][i]=INF; for(int i=0;i<=n+1;i++)p[i][0]='#',p[i][m+1]='#',len[i][0]=len[i][m+1]=INF; for(int i=1;i<=n;i++) { getchar(); for(int j=1;j<=m;j++) { cin>>p[i][j]; if(p[i][j]=='X')x=i,y=j; if(p[i][j]=='#')len[i][j]=INF; //hiker_place是人可能在的地方的隊列集合,is_hiker是判斷該點是否可能有人 if(p[i][j]=='O')hiker_place.push({i,j}),is_hiker[{i,j}]=1; } } //找X到O的最遠距離 bfs(x,y); string ans=""; while(!hiker_place.empty()) { int max_len=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(len[i][j]==INF)continue; else if(is_hiker[{i,j}]&&len[i][j]>max_len)max_len=len[i][j]; } } string tmp=""; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(is_hiker[{i,j}]&&len[i][j]==max_len) { string path=cal_path(i,j); if(tmp==""||path<tmp)tmp=path; } } } ans+=tmp; //清空人的位置,將該步所有人的可能位置按照tmp指令進行模擬,得到新的所有人的可能位置,賦值給queue及map is_hiker.clear(); queue<pair<int, int> > tmp_place; while(!hiker_place.empty()) { pair<int, int> cur=hiker_place.front(),nex; hiker_place.pop(); nex=walk(cur.first,cur.second,tmp); if(!is_hiker[nex]&&p[nex.first][nex.second]!='X') { is_hiker[nex]=1; tmp_place.push(nex); } } hiker_place=tmp_place; } cout<<ans<<endl; return 0; }