前言:距离四级考试剩27天,PAT甲级考试剩28天
对PAT甲级练习题做总结
1001 A+B Format (20 分)
- 题目大意:输入一对整数a,b,计算它们的和,输出格式为3个数字一组
- 题目解析:把a+b的和转换为字符串输出,从后往前看,下标对3取模,当值为0的时候,后面输出逗号,最后一位不用输出逗号
- 注意:如果为负号或者最后一位,跳过不用输出逗号
英语单词:
calculate /ˈkælkjuleɪt/ v. 计算,核算;预测,推测
comma /ˈkɒmə/ n. 逗号;停顿
be separated into groups of three by commas
被用逗号分离成3个一组
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int main(){
int a,b;cin>>a>>b;
int sum = a+b;
string s = to_string(sum);
int n = s.size();
for(int i = 0; i < n; i ++ ){
cout<<s[i];
if(s[i] == '-' || i == n - 1) continue;
if((n - 1 - i)%3 == 0) cout<<",";
}
return 0;
}
1002 A+B for Polynomials (25 分)
-
题目大意:输出两个多项式A、B求和,指数相同,系数相加
-
题目解析:用map容器存多项式,first为指数,second为系数,如果系数为0,则删除它
-
注意:以输入相同的格式进行输出,从大到小输出
英语单词:
exponents and coefficients 指数和系数
respectively /rɪˈspektɪvli/ adv. 分别地,依次地
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n,m;
vector<int> ids;
map<int,double> pol;
int main(){
cin >> n;
for(int i = 0; i < n; i ++ ){
int idx;double val;
cin >> idx >> val;
pol[idx] += val;
}
cin >> m;
for(int i = 0; i < m; i ++ ){
int idx;double val;
cin >> idx >> val;
pol[idx] += val;
}
for(auto &[k,v] : pol){
if(pol[k]) ids.push_back(k);
}
sort(ids.begin(),ids.end(),greater<>());
printf("%d",ids.size());
for(auto id : ids){
printf(" %d %.1f",id,pol[id]);
}
return 0;
}
1003 Emergency (25 分)
-
题目大意:
求从当前城市C1到目标城市C2,最短的时间并且召集最多的人,最短路径的条数 -
题目解析:
Dijkstra求最短路,第一标尺为距离,第二标尺为点权
核心代码:
初始化:
path[st] = 1;
nums[st] = w[st];
if(dist[j] > dist[t] + g[t][j]){
dist[j] = dist[t] + g[t][j];
path[j] = path[t];
nums[j] = nums[t] + w[j];
}else if(dist[j] == dist[t] + g[t][j]){
path[j] += path[t];
if(nums[j] < nums[t] + w[j]){
nums[j] = nums[t] + w[j];
}
}
英语单词:
scattered /ˈskætəd/ adj. 分散的;散乱的
mark 做标记,分数
emergency n. 突发事件,紧急情况 adj. 紧急情况下的;应急的
guaranteed /ˌɡærənˈtiːd/ 保证,有保证的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
int n,m,st,ed;
int g[N][N];
bool vis[N];
int w[N],dist[N],nums[N],path[N];
void dijkstra(){
memset(dist,0x3f,sizeof dist);
dist[st] = 0;
path[st] = 1;
nums[st] = w[st];
for(int i = 0; i < n; i ++ ){
int t = -1;
for(int j = 0; j < n; j ++ ){
if(!vis[j] && (t == -1 || dist[t] > dist[j])) t = j;
}
vis[t] = true;
for(int j = 0; j < n; j ++ ){
if(dist[j] > dist[t] + g[t][j]){
dist[j] = dist[t] + g[t][j];
path[j] = path[t];
nums[j] = nums[t] + w[j];
}else if(dist[j] == dist[t] + g[t][j]){
path[j] += path[t];
if(nums[j] < nums[t] + w[j]){
nums[j] = nums[t] + w[j];
}
}
}
}
}
int main(){
cin >> n >> m >> st >> ed;
for(int i = 0; i < n; i ++ ) cin >> w[i];
memset(g,0x3f,sizeof g);
for(int i = 0; i < m; i ++ ){
int a,b,c;cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b],c);
}
dijkstra();
cout<<path[ed]<<" "<<nums[ed];
return 0;
}
1004 Counting Leaves (30 分)
-
题目大意:
给你个树,找每层有几个节点,ojk? -
题目解析:
深搜记录每层没有儿子的节点,并且找出最大层数
英语单词:
seniority /ˌsiːniˈɒrəti/ n. 年长,职位高;资历,年资
represent 代表,象征,表示,表现
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
typedef pair<int,int> pii;
int n,m;
vector<int> v[N];
int ans[N];
int dep;
void dfs(int u,int level){
if(v[u].size() == 0){
ans[level] += 1;
dep = max(dep,level);
}
for(auto j : v[u]){
dfs(j,level+1);
}
}
int main(){
cin >> n >> m;
for(int i = 0; i < m; i ++ ){
int id,k;cin>>id>>k;
for(int j = 0; j < k; j ++ ){
int x;cin>>x;
v[id].push_back(x);
}
}
dfs(1,1);
for(int i = 1; i <= dep; i ++){
if(i - 1) cout<<' ';
cout<<ans[i];
}
return 0;
}
1005 Spell It Right (20 分)
-
题目大意:
求给定的非负整数每位数字之和,并用英文输出这个值的每位数字 -
题目解析:
值很大,用字符串输入,ojk?
英语单词:
task 作业,任务
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
typedef pair<int,int> pii;
char alp[20][20] = {"zero","one","two","three","four","five","six","seven","eight","nine","ten"};
int main(){
string s;cin>>s;
int sum = 0;
for(auto c : s) sum+=c-'0';
s = to_string(sum);
bool flag = false;
for(auto c : s){
if(flag) cout<<' ';
cout<<alp[c-'0'];
flag = true;
}
return 0;
}
1006 Sign In and Sign Out (25 分)
-
题目大意:
每天都有人来电脑房,找出第一个开门的和最后一个关门的人。ojk? -
题目解析:
模拟题,时间转换为秒钟计算
英语单词:
moment /ˈməʊmənt/ n. 片刻,瞬间;某一时刻
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
typedef pair<int,int> pii;
int work(string s){
int st = 0;
int sum = 0;
int n = s.size();
string a = "";
for(int i = 0; i < n; i ++ ){
if(s[i] == ':'){
a = s.substr(st,i-st);
sum = (sum + stoi(a))*60;
st = i+1;
}
}
a = s.substr(st,n - st);
sum += stoi(a);
//cout<<a<<endl;
return sum;
}
int main(){
int n;cin>>n;
int mi = 1e9,mx = -1e9;
string id_mi = "",id_mx = "";
for(int i = 0; i < n; i ++ ){
string a,b,c;cin>>a>>b>>c;
int tim_b = work(b);
int tim_c = work(c);
if(mi > tim_b) mi=tim_b,id_mi=a;
if(mx < tim_c) mx=tim_c,id_mx=a;
}
cout<<id_mi<<" "<<id_mx<<endl;
return 0;
}
1007 Maximum Subsequence Sum (25 分)
-
题目大意:
找出给定序列中,最大连续子序列和,并且找到该子序列第一个和最后一个数字。
英语单词:
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef pair<int,int> pii;
int n;
int a[N],dp[N];
int l[N],r[N];
int main(){
cin >> n;
for(int i = 1; i <= n; i ++ ) cin>>a[i],dp[i] = a[i];
l[0] = r[0] = 1;
for(int i = 1; i <= n; i ++ ){
if(dp[i - 1] + a[i] >= dp[i]){
dp[i] = dp[i - 1] + a[i];
l[i] = l[i - 1];
r[i] = i;
}else{
l[i] = i,r[i] = i;
}
}
int ans = -1,pos = 1;
for(int i = 1; i <= n; i ++ ){
if(dp[i] > ans){
ans = dp[i];
pos = i;
}
}
if(ans >= 0) printf("%d %d %d",ans,a[l[pos]],a[r[pos]]);
else printf("%d %d %d",0,a[1],a[n]);
return 0;
}
1008 Elevator (20 分)
- 题目大意:
从第0层出发,上一层花费6分钟,下一层花费4分钟,停止一次花费5分钟;求这一过程花费总时间。 - 题目解析:
模拟题意
英语单词:
denote 表示,指示,意思是
in specified order 按照指定的顺序
fulfill 履行,实现
elevator 电梯
total 总的,合计,全部的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
typedef pair<int,int> pii;
int main(){
int n;cin>>n;
int sum = 0,last = 0;
for(int i = 0; i < n; i ++ ){
int x;cin>>x;
if(x > last) sum += (x - last)*6 + 5;
else sum += (last - x)*4 + 5;
last = x;
}
cout<<sum;
return 0;
}
1009 Product of Polynomials (25 分)
-
题目大意:
模拟多项式乘法 -
题目解析:
多项式相乘,各项指数相加,系数相乘,ojk?
英语单词:
Please be accurate up to 1 decimal place.
精确到小数点后一位
accurate 准确的,精确的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
typedef pair<int,int> pii;
int n,m;
vector<int> ids;
map<int,double> a,b,c;
int main(){
cin >> n;
for(int i = 0; i < n; i ++ ){
int e;double co;cin>>e>>co;
a.insert({e,co});
}
cin >> m;
for(int i = 0; i < m; i ++ ){
int e;double co;cin>>e>>co;
b.insert({e,co});
}
for(auto &[k1,v1] : a){
for(auto &[k2,v2] : b){
c[k1+k2] += v1*v2;
if(!c[k1+k2]) c.erase(k1+k2);
}
}
printf("%d",c.size());
for(auto &[k,v]:c){
ids.push_back(k);
}
sort(ids.begin(),ids.end(),greater<>());
for(auto id : ids){
printf(" %d %.1f",id,c[id]);
}
return 0;
}
1010 Radix (25 分)
- 题目大意:
如果tag=1,给出radix是N1的基数,找到另一个基数满足N1=N2,反之亦然
- 题目解析:
用二分法找另外一个基数
英语单词:
radix 根,基数
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef pair<int,int> pii;
typedef long long LL;
LL convert(string s,LL r){
LL sum = 0,d = 1;
int n = s.size();
for(int i = n - 1; i >= 0; i -- ){
LL num = isdigit(s[i])?(s[i]-'0'):(s[i] - 'a' + 10);
sum += d*num;
d *= r;
}
return sum;
}
LL find_decimal(string n,LL nums){
char it = *max_element(n.begin(), n.end());
LL l = (isdigit(it) ? it - '0': it - 'a' + 10) + 1;
LL r = 1e18;
while(l < r){
LL mid = l+r>>1;
LL t = convert(n,mid);
if(t >= nums || t < 0) r = mid;
else l = mid + 1;
}
if(convert(n,r) == nums) return r;
return -1;
}
void solve(){
string a,b;LL tag,radix;
cin >> a >> b >> tag >> radix;
LL flag = tag == 1 ? find_decimal(b,convert(a,radix)) : find_decimal(a,convert(b,radix));
if(flag != -1){
printf("%lld\n",flag);
}else puts("Impossible");
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1011 World Cup Betting (20 分)
-
题目大意:
找出最大值并根据题目要求,输入答案 -
题目解析:
模拟题意即可
bet 打赌,下注
manner 方式,礼貌,态度,举止
lottery 彩票
triple 三倍
tie 平局,并列,平手
英语单词:
assign 分配,指定,指派,赋值
odd 奇怪的,奇数的,球险胜
correspond 相当,相符,类似于
profit 利益,获利
character 特性,描述,人物,字符
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef pair<int,int> pii;
typedef long long LL;
string alp="WTL";
void solve(){
vector<char> ans;
double sum = 1;
for(int i = 0; i < 3; i ++ ){
char c = 'W';double x;cin>>x;
for(int j = 1; j < 3; j ++ ){
double t;cin>>t;
if(t > x) x = t,c = alp[j];
}
ans.push_back(c);
sum *= x;
}
for(int i = 0; i < ans.size(); i ++ ){
if(i) cout<<' ';
cout<<ans[i];
}
printf(" %.2f",(sum*0.65 - 1)*2);
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1012 The Best Rank (25 分)
-
题目大意:
找出每个id的每课成绩和平均成绩的排名 -
题目解析:
结构体排序,不同id之间比较相同的科目
核心代码:
bool cmp(Stu a,Stu b){
return a.score[scoreby] > b.score[scoreby];
}
英语单词:
respect to 关心,考虑,尊敬
symbol 符号,象征,标志
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
typedef pair<int,int> pii;
typedef long long LL;
struct Stu{
int id,best;
int score[4],rank[4];
};
int n,m;
int scoreby = -1;
bool cmp(Stu a,Stu b){
return a.score[scoreby] > b.score[scoreby];
}
void solve(){
cin >> n >> m;
vector<Stu> stu(n);
for(int i = 0; i < n; i ++ ){
int id;cin>>id;
stu[i].id = id;
for(int j = 1; j < 4; j ++ ){
cin >> stu[i].score[j];
}
stu[i].score[0] = accumulate(stu[i].score+1,stu[i].score+4,0)/3;
}
for(scoreby = 0; scoreby < 4; scoreby ++){
sort(stu.begin(),stu.end(),cmp);
stu[0].rank[scoreby] = 1;
for(int i = 1; i < n; i ++ ){
if(stu[i].score[scoreby] != stu[i - 1].score[scoreby])
stu[i].rank[scoreby] = i + 1;
else
stu[i].rank[scoreby] = stu[i - 1].rank[scoreby];
}
}
unordered_map<int,pair<int,int>> index;
for(int i = 0; i < n; i ++ ){
int minr = stu[i].rank[0];
int best = 0;
for(int j = 1; j < 4; j ++ ){
if(stu[i].rank[j] < minr) minr = stu[i].rank[j],best = j;
}
index[stu[i].id] = {minr,best};
}
string alp = "ACME";
while(m --){
int id; cin >> id;
if(!index.count(id)) puts("N/A");
else printf("%d %c\n",index[id].first,alp[index[id].second]);
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1013 Battle Over Cities (25 分)
-
题目大意:
当一个城市被占领的时候,这个城市所连接的所有道路都会关闭。求需要修几条路才能让其他城市联通。 -
题目解析:
连通图问题,找出所有连通图,每个图连接一条边即可。
英语单词:
check 检查,审查
battle 战争,斗争
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef pair<int,int> pii;
typedef long long LL;
int n,m,k;
vector<int> g[N];
bool vis[N];
void dfs(int u){
vis[u] = true;
for(int j : g[u]){
if(vis[j]) continue;
dfs(j);
}
}
int count(int root){
memset(vis,false,sizeof vis);
vis[root] = true;
int cnt = 0;
for(int i = 1; i <= n; i ++ ){
if(!vis[i]) dfs(i),cnt+=1;
}
return cnt;
}
void solve(){
cin >> n >> m >> k;
for(int i = 0; i < m; i ++){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
while(k --){
int rt; cin >> rt;
printf("%d\n",count(rt)-1);
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1014 Waiting in Line (30 分)
-
题目大意:
银行有N个窗口,每个窗口前面占M个顾客,其他的顾客在黄线外面等待,如果前面有人走,黄线后面的就紧接着排队。
注意:银行8点开门,17点结束 -
题目解析:
比较麻烦的模拟题QWQ。
英语单词:
be served as 被充当,被服务
note that 注意
behind 后面
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef pair<int,int> pii;
typedef long long LL;
struct Node{
int poptime,endtime;
queue<int> q;
};
void solve(){
int n,m,k,q;cin>>n>>m>>k>>q;
vector<Node> window(n+1);
vector<int> tim(k+1),result(k+1);
vector<int> sorry(k+1,false);
for(int i = 1; i <= k; i ++ ) cin>>tim[i];
int idx = 1;
for(int i = 1; i <= m; i ++ ){
for(int j = 1; j <= n; j ++ ){
if(idx <= k){
window[j].q.push(tim[idx]);
if(window[j].endtime >= 540) sorry[idx] = true;
window[j].endtime += tim[idx];
if(i == 1) window[j].poptime = window[j].endtime;
result[idx++] = window[j].endtime;
}
}
}
while(idx <= k){
int tmpmin = window[1].poptime,tmpwindow = 1;
for(int i = 2; i <= n; i ++ ){
if(tmpmin > window[i].poptime){
tmpmin = window[i].poptime;
tmpwindow = i;
}
}
window[tmpwindow].q.pop();
window[tmpwindow].q.push(tim[idx]);
window[tmpwindow].poptime += window[tmpwindow].q.front();
if(window[tmpwindow].endtime >= 540) sorry[idx] = true;
window[tmpwindow].endtime += tim[idx];
result[idx++] = window[tmpwindow].endtime;
}
while(q--){
int query;cin>>query;
int minute = result[query];
if(sorry[query]) puts("Sorry");
else printf("%02d:%02d\n",(minute + 480)/60,(minute + 480)%60);
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1015 Reversible Primes (20 分)
- 题目大意:
可逆素数:本身是素数并且转换为D进制反转后也是素数 - 题目解析:
进制转换
英语单词:
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef pair<int,int> pii;
typedef long long LL;
int rever(int n,int radix){
string s = "";
do{
s += n%radix+'0';
n/=radix;
}while(n != 0);
int sum = 0,d = 1;
for(int i = s.size() - 1; i >= 0; i --){
sum += d*(s[i] - '0');
d *= radix;
}
return sum;
}
bool isprime(int n){
if(n < 2) return false;
for(int i = 2; i <= n/i; i ++ ){
if(n % i == 0){
return false;
}
}
return true;
}
void solve(){
int n,radix;
while(scanf("%d%d",&n,&radix) != 1){
int nn = rever(n,radix);
if(isprime(nn) && isprime(n)) puts("Yes");
else puts("No");
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1016 Phone Bills (25 分)
- 题目大意:
给你一堆电话记录,找到在线和离线的时间段,计算费用,ojk? - 题目解析:
时间转换,排序
英语单词:
toll 通行费,敲
chronologically 按年代地,从历史上,按时间顺序
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
struct Node{
string name;
int status,month,tim,day,hour,minute;
};
int n;
int rate[N];
bool cmp(Node a,Node b){
if(a.name != b.name)
return a.name<b.name;
if(a.tim != b.tim)
return a.tim<b.tim;
}
double billcount(Node call){
double cost = rate[call.hour]*call.minute+rate[24]*60*call.day;
for(int i = 0; i < call.hour; i ++) cost += rate[i]*60;
return cost/100.0;
}
void solve(){
for(int i = 0; i < 24; i ++ ){
cin>>rate[i];
rate[24] += rate[i];
}
cin>>n;
vector<Node> data(n);
for(int i = 0; i < n; i ++ ){
cin>>data[i].name;
scanf("%d:%d:%d:%d",&data[i].month,&data[i].day,&data[i].hour,&data[i].minute);
string tmp;cin>>tmp;
data[i].status = (tmp=="on-line")?1:0;
data[i].tim = data[i].day*24*60+data[i].hour*60+data[i].minute;
}
sort(data.begin(),data.end(),cmp);
map<string,vector<Node>> customer;
for(int i = 1; i < n; i ++ ){
if(data[i].name == data[i - 1].name && data[i-1].status == 1 && data[i].status == 0 )
{
customer[data[i - 1].name].push_back(data[i - 1]);
customer[data[i].name].push_back(data[i]);
}
}
for(auto it : customer){
vector<Node> tmp = it.second;
cout<<it.first;
printf(" %02d\n",tmp[0].month);
double sum = 0;
for(int i = 1; i < tmp.size(); i += 2){
double cost = billcount(tmp[i]) - billcount(tmp[i-1]);
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",
tmp[i-1].day,tmp[i-1].hour,tmp[i-1].minute,tmp[i].day,tmp[i].hour,tmp[i].minute,
tmp[i].tim-tmp[i-1].tim,cost);
sum += cost;
}
printf("Total amount: $%.2f\n",sum);
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1017 Queueing at Bank (25 分)
-
题目大意:
所有客户占到黄线外面,有K个窗口,窗口可以服务就去,8点开门,17点关门。 -
题目解析:
先来先服务辣
英语单词:
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
struct Node{
int come,wait;
}p[N];
int n,k;
bool cmp(Node a,Node b){
return a.come < b.come;
}
void solve(){
cin >> n >> k;
int cnt = 0;
for(int i = 1; i <= n; i ++ ){
int hh,mm,ss,wait;
scanf("%d:%d:%d %d",&hh,&mm,&ss,&wait);
int come = hh*60*60+mm*60+ss;
if(come > 17*60*60) continue;
p[++cnt].come = come;
p[cnt].wait = wait*60;
}
sort(p+1,p+cnt+1,cmp);
priority_queue<int,vector<int>,greater<int>> q;
for(int i = 1; i <= k; i ++ ) q.push(8*60*60);
double sum = 0;
for(int i = 1; i <= cnt; i ++ ){
int tt = q.top();q.pop();
if(tt <= p[i].come) q.push(p[i].come+p[i].wait);
else{
sum += tt-p[i].come;
q.push(tt+p[i].wait);
}
}
if(cnt) printf("%.1f",sum/60/cnt);
else puts("0.0");
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1018 Public Bike Management (30 分)
-
题目大意:
找出一个最短路径,其中需要补充的和带回去的最少。 -
题目解析:
Djikstra+DFS -
注意:
不能单独用Dijkstra,因为不能满足最优情况(不能保证需要最少或者带回去的最少),第二、三标尺只能通过遍历所有解找出最优解。
英语单词:
the above 以上所述
vertex 顶点
illustrate 说明,证实
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int cap,sp,n,m;
int g[N][N];
int c[N],dist[N];
bool vis[N];
int minback,mineed;
vector<int> pre[N];
vector<int> path,tmppath;
void dfs(int u){
tmppath.push_back(u);
if(u == 0){
int back = 0,need = 0;
for(int i = tmppath.size() - 1; i >= 0; i -- ){
int v = tmppath[i];
if(c[v] >= 0) back += c[v];
else{
if(back > (0 - c[v])){
back += c[v];
}else{
need += (0 - c[v]) - back;
back = 0;
}
}
}
if(need < mineed){
path = tmppath;
mineed = need;
minback = back;
}else if(need == mineed && back < minback){
path = tmppath;
minback = back;
}
tmppath.pop_back();
return ;
}
for(int i = 0; i < pre[u].size(); i ++ )
dfs(pre[u][i]);
tmppath.pop_back();
}
void dijkstra(){
memset(dist,0x3f,sizeof dist);
dist[0] = 0;
for(int i = 0; i <= n; i ++ ){
int t = -1;
for(int j = 0; j <= n; j ++ ){
if(!vis[j] && (t == -1 || dist[t] > dist[j]))
t = j;
}
if(t == -1) break;
vis[t] = true;
for(int j = 0; j <= n; j ++ ){
if(vis[j] || g[t][j] == inf) continue;
if(dist[j] > dist[t] + g[t][j]){
dist[j] = dist[t] + g[t][j];
pre[j].clear();
pre[j].push_back(t);
}else if(dist[j] == dist[t] + g[t][j]){
pre[j].push_back(t);
}
}
}
}
void solve(){
cin >> cap >> n >> sp >> m;
for(int i = 1; i <= n; i ++ ){
cin>>c[i];
c[i] -= cap/2;
}
memset(g,0x3f,sizeof g);
for(int i = 1; i <= m; i ++ ){
int a,b,c;cin>>a>>b>>c;
g[a][b] = g[b][a] = c;
}
dijkstra();
minback = mineed = 1e9;
dfs(sp);
printf("%d 0",mineed);
for(int i = path.size() - 2; i >= 0; i --){
printf("->%d",path[i]);
}
printf(" %d",minback);
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1019 General Palindromic Number (20 分)
- 题目大意:
判断一个以基地为b的数字N是否是回文数字 - 题目解析:
回文数,进制抓换 - 注意:
如果用字符串存的话,要用字符数组存。
当b<=10可以用字符串存。
英语单词:
palindromic adj. 回文的
be applied to 被用于,应用于
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
vector<string> ans;
bool judge(){
int len = ans.size();
for(int i = 0,j = len - 1; i < j; i ++,j --)
if(ans[i] != ans[j]) return false;
return true;
}
void show(){
for(int i = 0; i < ans.size(); i ++ ){
if(i) cout<<" ";
cout<<ans[i];
}
}
void convert(int n,int radix){
vector<string> s;
do{
s.push_back(to_string(n%radix));
n/=radix;
}while(n != 0);
reverse(s.begin(),s.end());
ans = s;
}
void solve(){
int n,base;
cin >> n >> base;
convert(n,base);
if(judge()){
puts("Yes");
}else puts("No");
show();
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1020 Tree Traversals (25 分)
- 题目大意:
给出后序和中序,求层序 - 题目解析:
二叉树的遍历问题
英语单词:
traversal 遍历,穿越
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n;
int in[N],post[N];
vector<pii> level;
unordered_map<int,int> pos;
int cnt = 10;
void dfs(int pr,int il,int ir,int u){
if(il > ir) return ;
int root = post[pr];
int ri = pos[root];
level.push_back({u,root});
dfs(pr-(ir-ri)-1,il,ri-1,u*2);
dfs(pr-1,ri+1,ir,u*2+1);
}
void solve(){
cin >> n;
for(int i = 0; i < n; i ++ ) cin >> post[i];
for(int i = 0; i < n; i ++ ) cin >> in[i],pos[in[i]] = i;
dfs(n-1,0,n-1,1);
sort(level.begin(),level.end());
bool flag = false;
for(auto u : level){
if(flag) cout<<" ";
flag = true;
cout<<u.second;
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1021 Deepest Root (25 分)
-
题目大意:
给你一个图,是一颗树或者多棵树。若是多颗树输出有多少棵树。如果是一棵树,找出一个根使得这棵树的高度最大 -
题目解析:
树的直径问题,首先任意找个点v遍历离这个点最远的点u,然后用那个最远的点u再次遍历这棵树,找出最大的高度并且记录这些点。
英语单词:
acyclic 非循环的
hence 因此,所以
In case 万一,如果
component 组件,部件,成分
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n;
vector<int> g[N];
bool vis[N];
vector<int> tmp;
set<int> alls;
int st,maxv;
void dfs(int u,int level){
if(level > maxv){
tmp.clear();
maxv = level;
tmp.push_back(u);
}else if(level == maxv){
tmp.push_back(u);
}
vis[u] = true;
for(auto v : g[u]) if(!vis[v]) dfs(v,level+1);
}
int count(){
int cnt = 0;
memset(vis,0,sizeof vis);
for(int i = 1; i <= n; i ++ ){
if(!vis[i]){
dfs(i,1),cnt++;
if(i == 1){
if(tmp.size() != 0) st = tmp[0];
for(auto v : tmp) alls.insert(v);
}
}
}
return cnt;
}
void solve(){
cin >> n;
for(int i = 0; i < n - 1; i ++ ){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
int cnt = count();
if(cnt != 1) printf("Error: %d components\n",cnt);
else{
memset(vis,0,sizeof vis);
tmp.clear();
maxv = 0;
dfs(st,1);
for(auto v : tmp) alls.insert(v);
for(auto v : alls) cout<<v<<endl;
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1022 Digital Library (30 分)
- 题目大意:
给出书籍的一些信息,根据这些信息来查找出符合信息的书的ID号 - 题目解析:
模拟题
英语单词:
abstract 摘要,文摘,抽象的,作品
assign 分配
assume 假设
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n,m;
map<string,vector<string>> info;
void solve(){
cin >> n;
for(int i = 0; i < n; i ++ ){
string id;cin>>id;
string s;
for(int j = 0; j < 3; j ++ ){
getline(cin,s);
info[s].push_back(id);
}
getline(cin,s);
stringstream ss(s);
while(ss>>s) info[s].push_back(id);
for(int j = 0; j < 2; j ++ ){
getline(cin,s);
info[s].push_back(id);
}
}
cin>>m;
getchar();
while(m --){
string op;
getline(cin,op);
cout<<op<<endl;
op = op.substr(3,op.size());
vector<string> ids = info[op];
sort(ids.begin(),ids.end());
for(int i = 0; i < ids.size(); i ++ ) printf("%s\n",ids[i].c_str());
if(!ids.size()) puts("Not Found");
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1023 Have Fun with Numbers (20 分)
- 题目大意:
判断这个数字的两倍是否于初始数字的数字排列一样。最后一行,输出这个数字。 - 题目解析:
高精度问题
英语单词:
duplication 复制品,重复
exactly 恰好,正确的,精确地
permutation 排列
property 所有物,财产,特性,性质
that is 也就是说,即
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
map<int,int> hs;
vector<int> A,C;
vector<int> add(vector<int> &A, vector<int> &B){
if(A.size() < B.size()) return add(B,A);
int t = 0;
vector<int> C;
for(int i = 0; i < A.size(); i ++ ){
t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(t);
return C;
}
bool judge(){
for(auto c : C){
hs[c] -= 1;
if(hs[c] == 0) hs.erase(c);
}
if(hs.size() == 0)
return true;
else
return false;
}
void solve(){
string s;cin>>s;
for(auto c : s) hs[c-'0'] += 1;
for(int i = s.size() - 1; i >= 0; i --) A.push_back(s[i]-'0');
C = add(A,A);
if(judge()) puts("Yes");
else puts("No");
for(int i = C.size() - 1; i >= 0; i -- ) cout<<C[i];
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1024 Palindromic Number (25 分)
-
题目大意:
给一个数字N,判断是否能经过K次翻转相加于原数字成为回文数字 -
题目解析:
高精度 -
注意:初始数字是回文数字,则直接输出0
英语单词:
via 通过,经过
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
vector<int> A,B;
vector<int> add(vector<int> &A,vector<int> &B){
if(A.size() < B.size()) return add(B,A);
int t = 0;
vector<int> C;
for(int i = 0; i < A.size(); i ++ ){
t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(t);
return C;
}
bool judge(vector<int> &A){
for(int i = 0,j = A.size() - 1; i < j; i ++,j--){
if(A[i] != A[j]) return false;
}
return true;
}
void solve(){
string s;cin>>s;
int k;cin>>k;
for(int i = s.size()-1; i >= 0; i --) A.push_back(s[i]-'0');
int i = 0;
for(i = 0; i < k; i ++ ){
if(judge(A)) break;
B = A;
reverse(B.begin(),B.end());
A = add(A,B);
}
for(int i = A.size() - 1; i >= 0; i --) cout<<A[i];
puts("");
printf("%d",i);
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1025 PAT Ranking (25 分)
- 题目大意:
PAT考试有几个考场,最后合并排名。
求当前考场排名,合并考场后的排名,ojk? - 题目解析:
排序题
英语单词:
simultaneously 同时地
immediately 立刻地
generate 产生,生成
testee 测试对象,受测者,考生
registration 登记,注册
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n,k;
struct Stu{
string id;
int score,rk1,rk2,pos;
};
bool cmp(Stu a,Stu b){
return a.score!=b.score?a.score>b.score:a.id<b.id;
}
void solve(){
cin >> n;
vector<Stu> stus;
for(int i = 1; i <= n; i ++ ){
cin >> k;
vector<Stu> tmp;
for(int j = 1; j <= k; j ++ ){
string id;int score;
Stu stu;
cin>>id>>score;
stu.id = id,stu.score = score;
stu.pos = i;stu.rk1=stu.rk2=0;
tmp.push_back(stu);
}
sort(tmp.begin(),tmp.end(),cmp);
tmp[0].rk2 = 1;
stus.push_back(tmp[0]);
for(int i = 1; i < k; i ++ ){
if(tmp[i].score != tmp[i - 1].score){
tmp[i].rk2 = i + 1;
}else{
tmp[i].rk2 = tmp[i - 1].rk2;
}
stus.push_back(tmp[i]);
}
}
sort(stus.begin(),stus.end(),cmp);
stus[0].rk1 = 1;
int nn = stus.size();
printf("%d\n",nn);
printf("%s %d %d %d\n",stus[0].id.c_str(),stus[0].rk1,
stus[0].pos,stus[0].rk2);
for(int i = 1; i < nn; i ++ ){
if(stus[i].score != stus[i - 1].score){
stus[i].rk1 = i + 1;
}else stus[i].rk1 = stus[i - 1].rk1;
printf("%s %d %d %d\n",stus[i].id.c_str(),stus[i].rk1,
stus[i].pos,stus[i].rk2);
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1026 Table Tennis (30 分)
乒乓球暂时不写,QWQ
- 题目大意:
- 题目解析:
英语单词:
代码如下:
1027 Colors in Mars (20 分)
-
题目大意:
在火星上,它们用基地13来代替16。给出三个十进制数转换为13进制。如果是单个数字,前面需要补0 -
题目解析:
进制转换
英语单词:
upper-case 大写字母
decimal 十进制的,小数的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int red,green,blue;
string alp = "0123456789ABC";
string convert(int n,int radix){
string s = "";
do{
s += alp[n%radix];
n/=radix;
}while(n!=0);
reverse(s.begin(),s.end());
if(s.size() == 1) s = "0" + s;
return s;
}
void solve(){
cin >> red >> green >> blue;
string ans = "#";
ans += convert(red,13) + convert(green,13) + convert(blue,13);
printf("%s",ans.c_str());
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1028 List Sorting (25 分)
- 题目大意:
如果C=1,对ID进行递增排序;C=2,对名字进行非递减排序;C=3,对成绩进行非递减排序; - 题目解析:
排序题
英语单词:
imitate 模仿,仿效,仿制
inclusive 包含的,对外开放的,包容广阔的
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
struct Stu{
string id,name;
int score;
};
bool cmp1(Stu a,Stu b){
return a.id < b.id;
}
bool cmp2(Stu a,Stu b){
if(a.name != b.name) return a.name<b.name;
return a.id < b.id;
}
bool cmp3(Stu a,Stu b){
if(a.score != b.score) return a.score<b.score;
return a.id < b.id;
}
void solve(){
int n,k;cin>>n>>k;
vector<Stu> stus;
for(int i = 0; i < n; i ++ ){
string id,name;int score;
cin>>id>>name>>score;
stus.push_back({id,name,score});
}
if(k == 1) sort(stus.begin(),stus.end(),cmp1);
else if(k == 2) sort(stus.begin(),stus.end(),cmp2);
else sort(stus.begin(),stus.end(),cmp3);
for(auto stu : stus){
cout<<stu.id<<" "<<stu.name<<" "<<stu.score<<endl;
}
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1029 Median (25 分)
- 题目大意:
给两个序列,找到合并后序列里的中位数 - 题目解析:
排序题
英语单词:
median 中值,中位数
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n,m;
void solve(){
cin >> n;
vector<LL > A;
for(int i = 0; i < n; i ++ ){
int x;cin>>x;
A.push_back(x);
}
cin >> m;
for(int i = 0; i < m; i ++ ){
int x;cin>>x;
A.push_back(x);
}
sort(A.begin(),A.end());
cout<<A[(n+m-1)/2];
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}
1030 Travel Plan (30 分)
- 题目大意:
找出起始位置到终点的最短距离,第二标尺最小花费 - 题目解析:
Dijkstra裸题
英语单词:
destination 目的地,终点
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
const int inf = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef long long LL;
int n,m,st,ed;
int g[N][N],w[N][N];
bool vis[N];
int dist[N],cost[N],path[N];
vector<int> tmp;
void dijkstra(){
memset(dist,0x3f,sizeof dist);
memset(cost,0x3f,sizeof cost);
dist[st] = 0;
cost[st] = 0;
for(int i = 0; i < n; i ++ ){
int t = -1;
for(int j = 0; j < n; j ++ ){
if(!vis[j] && (t == -1 || dist[t] > dist[j]))
t = j;
}
vis[t] = true;
for(int j = 0; j < n; j ++ ){
if(dist[j] > dist[t] + g[t][j]){
dist[j] = dist[t] + g[t][j];
cost[j] = cost[t] + w[t][j];
path[j] = t;
}else if(dist[j] == dist[t] + g[t][j]){
if(cost[j] > cost[t] + w[t][j]){
cost[j] = cost[t] + w[t][j];
path[j] = t;
}
}
}
}
}
void dfs(int u){
tmp.push_back(u);
if(u == st){
return ;
}
dfs(path[u]);
}
void solve(){
cin >> n >> m >> st >> ed;
memset(g,0x3f,sizeof g);
memset(w,0x3f,sizeof w);
for(int i = 0; i < m; i ++ ){
int a,b,c1,c2;cin>>a>>b>>c1>>c2;
g[a][b] = g[b][a] = c1;
w[a][b] = w[b][a] = c2;
}
dijkstra();
dfs(ed);
reverse(tmp.begin(),tmp.end());
bool ok = false;
for(auto x : tmp){
if(ok) cout<<" ";
cout<<x;
ok=true;
}
printf(" %d %d",dist[ed],cost[ed]);
}
int main(){
int _; _=1;
while(_--) solve();
return 0;
}