前言:距离四级考试剩25天,PAT甲级考试剩26天
对PAT甲级练习题做总结
- 2021/11/22
1031 1032 1033 (3题)
- 2021/11/23
1034 1035 1036 1037 1038 1039 1040 1041 (8题)
今天水题比较多吧,还是先刷完为主(看英文辣,后面回头多练练生疏的题目,那些码量大的
1031 Hello World for U (20 分)
-
题目大意:
给一个字符串,按找U形输出,左n1下n2右n3,其中n1和n3取相同的值,并且小于等于n2,n1+n2+n3=N+2 -
题目解析:
-
n1=n3=(N+2)/3
-
n2=(N+2)/3+(N+2)%3
英语单词:
vertical 垂直的,竖直
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
char str[N][N];
int main(){
string s;cin>>s;
int n = s.size(),cnt = 0;
n+=2;
int row = n/3,col = n/3+n%3;
for(int i = 0; i < row; i ++ ){
for(int j = 0; j < col; j ++ ){
str[i][j] = ' ';
}
}
//cout<<n<<" "<<row<<" "<<col<<endl;
int i = 0;
while(i < row) str[i++][0] = s[cnt++];
cnt --, i = 0;
while(i < col) str[row-1][i++] = s[cnt++];
cnt --,i = row-1;
while(i >= 0) str[i--][col-1] = s[cnt++];
for(int i = 0; i < row; i ++ ){
for(int j = 0; j < col; j ++ ){
cout<<str[i][j];
}
puts("");
}
return 0;
}
1032 Sharing (25 分)
- 题目大意:
找出两个链表共同的后缀 - 题目解析:
模拟链表操作
英语单词:
suffix 后缀
sublist 子表
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
/*
11111 - 00001 - 00010 - 12345 - 67890 - 00002
- 00003 -1
2222 - 23456 - 67890 - 00002 - 00003 -1
*/
int n1,n2,m;
int ne[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n1 >> n2 >> m;
while(m --){
int a,b;char c;
cin >> a >> c >> b;
ne[a] = b;
}
map<int,int> hs;
while(n1 != -1) hs[n1] = true,n1 = ne[n1];
int ans = -1;
while(n2 != -1){
if(hs[n2]) {ans = n2;break;}
n2 = ne[n2];
}
if(ans == -1) cout<<"-1";
else printf("%05d",ans);
return 0;
}
1033 To Fill or Not to Fill (25 分)
-
题目大意:
-
题目解析:
贪心,比较难写,看的柳神代码,先往后写着,鸽一下
英语单词:
tank 罐,桶
gas station 加油站
route 路线
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
#define dis first
#define pri second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int n;
db cmx,finald,davg;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> cmx >> finald >> davg >> n;
vector<pair<db,db>> v;
v.push_back({finald,0});
for(int i = 0; i < n; i ++ ){
db pri,dis;cin>>pri>>dis;
v.push_back({dis,pri});
}
sort(v.begin(),v.end());
db nowdis = 0,mxdis = 0,nowpri = 0,totpri = 0,leftdis = 0;
if(!v[0].dis) nowpri = v[0].pri;
else {printf("The maximum travel distance = 0.00\n");return 0;}
while(nowdis < finald){
mxdis = davg*cmx + nowdis;
db mipridis = 0,mipri = inf;
bool ok = false;
for(int i = 1; i <= n && v[i].dis <= mxdis; i ++ ){
if(v[i].dis <= nowdis) continue;
if(v[i].pri < nowpri){
totpri += (v[i].dis - nowdis - leftdis)*nowpri/davg;
leftdis = 0;
nowpri = v[i].pri;
nowdis = v[i].dis;
ok = true;
break;
}
if(v[i].pri < mipri){
mipri = v[i].pri;
mipridis = v[i].dis;
}
}
if(!ok && mipri != inf){
totpri += (nowpri * (cmx - leftdis/davg));
leftdis = cmx*davg - (mipridis-nowdis);
nowpri = mipri;
nowdis = mipridis;
}
if(!ok && mipri == inf){
nowdis += cmx*davg;
printf("The maximum travel distance = %.2f\n",nowdis);
return 0;
}
}
printf("%.2f\n",totpri);
return 0;
}
1034 Head of a Gang (30 分)
-
题目大意:
根据通话记录来判断一个团伙,也就是一个连通集合。其中,通话权值最大的就是头目 -
题目解析:
用dfs找到所有连通集合,并找出集合大小和集合中最大的点 -
注意:
本题可能存在回路问题,因此,先判断是否有边再判断是否有点。并查集写不了qwq
核心代码:
if(g[u][i]){
sum += g[u][i];
g[u][i] = g[i][u] = 0;
if(!vis[i]) dfs(i);
}
英语单词:
gang 帮派,团伙
weight 权重,重量
relation 关系
cluster 群,群集,组
threshold 门槛,阈值
maximum 最大限度,最大量
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3+10;
const int inf = 0x3f3f3f3f;
#define dis first
#define pri second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int n,m,k;
map<string,int> hs;
map<int,string> sh;
int g[N][N],w[N];
bool vis[N];
int sum,cnt,idx;
void dfs(int u){
vis[u] = true;
if(w[u] > w[idx]) idx = u;
cnt++;
for(int i = 1; i <= n; i ++ ){
if(g[u][i]){
sum += g[u][i];
g[u][i] = g[i][u] = 0;
if(!vis[i]) dfs(i);
}
}
}
int main(){
cin >> m >> k;
for(int i = 0; i < m; i ++ ){
string a,b;int c;
cin>>a>>b>>c;
if(!hs[a]) hs[a] = ++n,sh[n] = a;
if(!hs[b]) hs[b] = ++n,sh[n] = b;
int na = hs[a],nb = hs[b];
g[na][nb]+=c,g[nb][na]+=c;
w[na] += c,w[nb] += c;
}
map<string,int> ans;
for(int i = 1; i <= n; i ++ ){
sum = cnt = idx = 0;
if(!vis[i]) dfs(i);
if(cnt > 2 && sum > k) ans[sh[idx]] = cnt;
}
if(!ans.size()) printf("0");
else{
printf("%d\n",ans.size());
for(auto &[k,v] : ans) cout<<k<<" "<<v<<endl;
}
return 0;
}
1035 Password (20 分)
- 题目大意:
不多说看代码。 - 题目解析:
模拟题 - 注意:
输出的时候,注意输出语句,仔细读题
There are N accounts and no account is modified
There is 1 account and no account is modified
英语单词:
judge 法官,评判
confusing 混淆的,令人困惑的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int n;
int check(string &s){
int flag = -1;
for(auto &c : s){
if(c == '1') flag = 1,c = '@';
if(c == '0') flag = 1,c = '%';
if(c == 'l') flag = 1,c = 'L';
if(c == 'O') flag = 1,c = 'o';
}
return flag;
}
int main(){
cin >> n;
vector<pair<string,string>> v,ans;
for(int i = 0; i < n; i ++ ){
string a,b;cin>>a>>b;
v.push_back({a,b});
}
bool ok = true;
for(auto &t : v){
int c = check(t.y);
if(c != -1) ok = false,ans.push_back(t);
}
if(ok){
if(n==1) printf("There is %d account and no account is modified\n",n);
else printf("There are %d accounts and no account is modified\n",n);
}
else{
printf("%d\n",ans.size());
for(auto t : ans) cout<<t.x<<" "<<t.y<<endl;
}
return 0;
}
1036 Boys vs Girls (25 分)
-
题目大意:
找出男生最低成绩和女生最高成绩 -
题目解析:
模拟题
英语单词:
absent 缺席,缺乏
miss 错过,丢失,思念
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int n;
map<int,pair<string,string>> female,male;
int main(){
cin >> n;
for(int i = 0; i < n; i ++ ){
string name,gender,id;int grade;
cin>>name>>gender>>id>>grade;
if(gender == "M"){
male[grade] = {name,id};
}else{
female[-grade] = {name,id};
}
}
int n1 = 0,n2 = 0;
for(auto t : female){
n1 = -t.x;
cout<<t.y.x<<" "<<t.y.y<<endl;
break;
}
if(!n1) puts("Absent");
for(auto t : male){
n2 = t.x;
cout<<t.y.x<<" "<<t.y.y<<endl;
break;
}
if(!n2) puts("Absent");
if(n1 && n2) cout<<n1-n2<<endl;
else puts("NA");
return 0;
}
1037 Magic Coupon (25 分)
-
题目大意:
不多说看代码。 -
题目解析:
模拟题
英语单词:
coupon 优惠卷,赠卷,折扣卷
What is more 更重要的是,而且
bonus 奖金,律贴
at most 最多
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int main(){
int n,m;
vector<int> v1,v2,v3,v4;
cin>>n;
for(int i = 0; i < n; i ++ ){
int x;cin>>x;
if(x > 0) v1.push_back(-x);
if(x < 0) v2.push_back(x);
}
cin>>m;
for(int i = 0; i < m; i ++ ){
int x;cin>>x;
if(x > 0) v3.push_back(-x);
if(x < 0) v4.push_back(x);
}
int ans = 0;
int n1 = v1.size(),n2 = v2.size();
int n3 = v3.size(),n4 = v4.size();
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
sort(v3.begin(),v3.end());
sort(v4.begin(),v4.end());
for(int i = 0; i < min(n1,n3); i ++){
ans += v1[i]*v3[i];
}
for(int i = 0; i < min(n2,n4); i ++){
ans += v2[i]*v4[i];
}
cout<<ans;
return 0;
}
1038 Recover the Smallest Number (30 分)
- 题目大意:
给一些数字,求它们组合后最小数字组合 - 题目解析:
贪心,很巧妙的运用的cmp函数
核心代码:
bool cmp(string a,string b){
return a + b < b + a;
}
英语单词:
recover 恢复
segment 段,线段,部分,分割
combination 混合,结合
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
bool cmp(string a,string b){
return a + b < b + a;
}
int main(){
int n;cin>>n;
vector<string> v(n);
for(auto &s : v) cin >> s;
sort(v.begin(),v.end(),cmp);
string ans = "";
for(auto &s : v) ans+=s;
while(ans.size() && ans[0] == '0') ans.erase(ans.begin());
if(ans.size()) cout<<ans;
else cout<<"0";
return 0;
}
1039 Course List for Student (25 分)
- 题目大意:
不多说看代码。 - 题目解析:
模拟题
英语单词:
look for 寻找
capital 资本,首都,资金,大写
indices 指数,目录(index的复数)
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int n,m;
int main(){
cin >> n >> m;
map<string,vector<int>> info;
for(int i = 0; i < m; i ++ ){
int id,k;cin>>id>>k;
for(int j = 0; j < k; j ++ ){
string s; cin >> s;
info[s].push_back(id);
}
}
while(n --){
string s; cin >> s;
cout<<s;
printf(" %d",info[s].size());
vector<int> ids = info[s];
sort(ids.begin(),ids.end());
for(auto &id : ids) cout<<" "<<id;
puts("");
}
return 0;
}
1040 Longest Symmetric String (25 分)
- 题目大意:
因为不知道symmetric单词的意思,以为是让求最长sxxxs这样类似的子串,首尾一个s。但是交了一发,发现答案错误一堆,第一个测试点竟然过了ojk。
那么,来跟我一起读:
symmetric 对称的 symmetric 对称的 symmetric 对称的
题目让求最长对称子串。
- 题目解析:
暴力求解,dp后来有时间再补,先往后写
英语单词:
symmetric 对称的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int main(){
string s;getline(cin,s);
int n = s.size();
int mx = 1;
for(int i = 0; i < n; i ++ ){
for(int j = i + 1; j < n; j ++ ){
string t = s.substr(i,j - i + 1);
string t1 = t;
reverse(t1.begin(),t1.end());
if(t == t1) mx = max(mx,j - i + 1);
}
}
cout<<mx;
return 0;
}
1041 Be Unique (20 分)
- 题目大意:
找最早出现的不重复数字 - 题目解析:
模拟题
英语单词:
乌拉
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int,int> pii;
typedef double db;
/*
*/
int main(){
int n; cin >> n;
map<int,int> hs;
vector<int> v(n);
for(auto &x : v) cin >> x,hs[x] += 1;
int ans = -1;
for(auto &x : v) if(hs[x] == 1) {ans = x;break;}
if(ans == -1) puts("None");
else cout<<ans;
return 0;
}