PAT甲级2020年秋季题目记录分析
题目在官方可以买到,就五块钱:https://pintia.cn/market/item/1302817001358053376。但是因为有时间限制(3小时候就不能提交了)所以,我是看别的的博客题目截图,写完了,才去买来看看自己对不对的。
1.大熊猫和盆盆奶。
解题思路:
1.把猫从左往右喂一遍,保证每个猫不和自己左边的吵架。
因为左1猫没有左邻居了,他不攀比,直接最少量200.
其余猫,就看自己体重和左邻居的关系了,比他重就比他多100,一样重一样的奶,轻就最少量200.
2.把猫从右往左喂一遍,保证每个猫不和自己右边的吵架。
因为右1猫没有右邻居了,他不攀比,直接最少量200.
其余猫,就看自己体重和右邻居的关系了,比他重就比他多100,一样重一样的奶,轻就最少量200.
3.喂完两遍奶后,每只熊猫都喂了两次,取喝的多的那次的量,这只猫就和左右都不吵架哦了。
代码:
//
// Created by 江左 on 2021/3/10.
//
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
int main() {
int n,sum=0;cin>>n;
vector<int> weight,leftToRight,rightToLeft;
weight.resize(n);
leftToRight.resize(n);
rightToLeft.resize(n);
for (int i = 0; i < n; ++i)
cin>>weight[i];
leftToRight[0]=200;
for (int i = 1; i < n; ++i) {
if(weight[i]>weight[i-1])
leftToRight[i]=leftToRight[i-1]+100;
else if(weight[i]==weight[i-1])
leftToRight[i]=leftToRight[i-1];
else
leftToRight[i]=200;
}
rightToLeft[n-1]=200;
sum+=max(leftToRight[n-1],rightToLeft[n-1]);
for (int i = n-2; i >= 0; --i) {
if(weight[i]>weight[i+1])
rightToLeft[i]=rightToLeft[i+1]+100;
else if(weight[i]==weight[i+1])
rightToLeft[i]=rightToLeft[i+1];
else
rightToLeft[i]=200;
sum+=max(leftToRight[i],rightToLeft[i]);
}
cout<<sum;
return 0;
}
2.有多少种方式买连续的岛
比较简单:
代码
//
// Created by 江左 on 2021/3/9.
//
#include <iostream>
using namespace std;
const int N = 10010;
int n,m;
int sum[N];
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
int x;cin >> x;
sum[i] = x + sum[i - 1];
}
int res = 0;
for(int i=1,j=0;i<=n;i++)
{
while(sum[i] - sum[j] > m)
j ++ ;
res += i - j;
}
cout << res << endl;
return 0;
}
3.给你一个二叉树的中序和前序,让你打印他的left-view。
说白了,就是自上而下,打印每一层最左边的节点。
解题思路:根据中序和先序,遍历二叉树的同时把每一个节点押入属于他的深度集合中。
//
// Created by 江左 on 2021/3/9.
//
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int in[30],pre[30];
map<int,int> m;
vector<vector<int>> v;
void level(int l,int r,int p,int dep){
int inRoot=m[pre[p]];
v[dep].push_back(in[inRoot]);
if(l<inRoot)
level(l,inRoot-1,p+1,dep+1);
if(inRoot<r)
level(inRoot+1,r,p+1+(inRoot-l),dep+1);
}
int main() {
int n;cin>>n;v.resize(n+1);
for (int i = 1; i <= n; ++i) {
cin>>in[i];
m[in[i]]=i;
}
for (int i = 1; i <= n; ++i)
cin>>pre[i];
level(1,n,1,0);
int p=0;
while (!v[p].empty()){
if(p!=0) cout<<" ";
cout<<v[p][0];
p++;
}
return 0;
}
4.Professional Ability Test
题目又臭又长,人都读傻了,因为我英语不好,理解起来很困难。
大意是:
PAT,有很多考试,比如你想考B,但是得考A,分数必须大于S,会得到一个D的优惠券。
输入:给你若干考试的关系,然后问你如果我想通过某个考试x,需要经历的流程。
如果关系中有环,则impossible,反之okay,
经历的流程考试要求,过程中最小的totalS,totalS可能重复,就要最大的totalD。
注意点:编辑器要使用clang,。。。。不知道为什么g++没有全对,如果有人知道,请不吝赐教。
还有最后一个节点有时超时,有时不超时,很明显把输入输出都改成printf和scanf就一定能过了,但是我懒。
代码:
#include <iostream>
#include <vector>
using namespace std;
/// 检查图是否有自环,应该用拓扑排序
/// 解题方法,找入度为零的点,没有就输出NO,有就删除这个点和关联边,继续下一次循环
class Node{
public:
int cnt=0;//自己入度的个数
vector<int> GOTO;//由自己发起的,去往的顶点
};
vector<vector<int>> post; //下标为i的节点的入度情况
vector<Node> G;//node集合
int w1[1010][1010];//储存路径的S值
int w2[1010][1010];//储存路径的D值
int minS=9999999,maxD=-1;
vector<int> temp,res;
void dfs(int root,int sumS,int sumD){
if(sumS>minS) return;//剪枝
temp.push_back(root);
if (post[root].empty()){
//找到起始根节点了
if(sumS<minS){
minS=sumS;
res=temp;
maxD=sumD;
}else if(sumS==minS){
if(sumD>maxD){
maxD=sumD;
res=temp;
}
}
temp.pop_back();
return;
}
for (int i = 0; i < post[root].size(); ++i) {
dfs(post[root][i],sumS+w1[post[root][i]][root],sumD+w2[post[root][i]][root]);
}
temp.pop_back();
}
int main() {
int n,m;cin>>n>>m;
post.resize(n);G.resize(n);
for (int i = 0; i < m; ++i) {
int a,b;cin>>a>>b>>w1[a][b]>>w2[a][b];
G[b].cnt++;G[a].GOTO.push_back(b);
post[b].push_back(a);
}
int k;cin>>k;
vector<int> input;input.resize(k);
for (int i = 0; i < k; ++i) {
cin>>input[i];
}
//拓扑排序验证他是否有自环现象,如果有则imp
bool flag=true;int p=0;
while (p<G.size()){
p++;
bool f= true;
for (int i = 0; i < G.size(); ++i) {
if (G[i].cnt==0){
f=false;
for (int j = 0; j < G[i].GOTO.size(); ++j) {
G[G[i].GOTO[j]].cnt--;
}
G[i].cnt=-1;
break;
}
}
if(f){//自环的标志,没有了入度为零的点
flag=false;
break;
}
}
if(flag){
//正确完成了拓扑排序
cout<<"Okay."<<endl;
}else{
cout<<"Impossible."<<endl;
}
for (int i = 0; i < k; ++i) {
int t=input[i];
minS=9999999,maxD=-1;
if(post[t].empty()){
cout<<"You may take test "<<t<<" directly."<<endl;
continue;
}
if(flag){
dfs(t,0,0);
for (int j = res.size()-1; j >= 0; --j) {
if(j!=res.size()-1) cout<<"->";
cout<<res[j];
}cout<<endl;
}else{
cout<<"Error."<<endl;
}
}
return 0;
}
总结跌跌撞撞考了满分,但是明显用的时间超过考试给的三个小时,大后天就要参加PAT2021年春季考了,希望取得好成绩,理想成绩是九十分,呜呜,不想二战。