PAT甲级2020年秋季题目记录分析(全部AC,简单易懂)

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年春季考了,希望取得好成绩,理想成绩是九十分,呜呜,不想二战。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值