• 2019秋季PAT甲级题解(无第一题)


    今年的2、3、4题比较简单,尴尬的是第1题一点思路都没有,甚至没想起用暴力求解得点分,是这次PAT很大的遗憾。

    我把考试时候的代码贴在下面,本人代码水平并不高,贴出来只为学习交流,不喜勿喷~

    7-2 Merging Linked Lists (25 分)

    思路:先区分长链短链,然后不断循环,依次取长链中两个点和短链中一个点加入到新链中,直到长链和短链都处理完。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int maxn=100010;
    int n,m1,m2,k;
    int f1,f2;
    vector<int>v[3],ans;
    
    struct node{
        int Address ,Data ,Next;
    }nodes[maxn];
    
    void merge(int a,int b){//合并过程,此时满足a>b
        int k1=0;
        int k2=0;
        int len2=v[b].size()-1;
        while(k1<v[a].size()||k2<v[b].size()){//若还有一个链没处理完
            if(k1<v[a].size()){ //将长链第一个点加到ans中
                ans.push_back(v[a][k1]);
                k1++;
            }
            if(k1<v[a].size()){ //将长链第二个点加到ans中
                ans.push_back(v[a][k1]);
                k1++;
            }
            if(k2<v[b].size()){ //将短链的一个点加到ans中
                ans.push_back(v[b][len2-k2]);
                k2++;
            }
        }
    }
    
    int main(){
        cin>>f1>>f2>>n;
        for(int i=0;i<n;++i){
            int add;
            scanf("%d",&add);
            nodes[add].Address=add;
            scanf("%d%d",&nodes[add].Data,&nodes[add].Next);
        }
        int p1=f1;//遍历第一条链
        while(p1!=-1){
            m1++;
            v[1].push_back(p1);
            p1=nodes[p1].Next;
        }
        int p2=f2;//遍历第二条链
        while(p2!=-1){
            m2++;
            v[2].push_back(p2);
            p2=nodes[p2].Next;
        }
        if(m1>m2){//区分出长链与短链
            merge(1,2);
        }else merge(2,1);
    
        for(int i=0;i<ans.size()-1;++i){
            int u=ans[i];
            printf("%05d %d %05d
    ",nodes[u].Address,nodes[u].Data,nodes[ans[i+1]].Address);
        }
        int u=ans[ans.size()-1];
        printf("%05d %d -1
    ",nodes[u].Address,nodes[u].Data);
        return 0;
    }

    7-3 Postfix Expression (25 分)

    这个题我开始没仔细研读题目,直接按树的中序遍历方式进行输出,发现不对后按照例子对中序遍历进行修改,惊喜的是这样居然就能AC了。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <string>
    using namespace std;
    const int maxn=25;
    int n,m1,m2,k;
    int father[maxn];
    
    struct node{
        string data;
        int lchild,rchild;
    }nodes[maxn];
    
    void inorder(int root){
        printf("(");
        if(nodes[root].rchild!=-1&&nodes[root].lchild==-1){
            cout<<nodes[root].data;
            if(nodes[root].rchild!=-1){
                inorder(nodes[root].rchild);
            }
            
        }else{
            if(nodes[root].lchild!=-1){
                inorder(nodes[root].lchild);
            }
            
            if(nodes[root].rchild!=-1){
                inorder(nodes[root].rchild);
            }
            cout<<nodes[root].data;
        }
        
        printf(")");
    }
    
    int findFather(int x){
        while(x!=father[x]){
            x=father[x];
        }
        return x;
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;++i){
            father[i]=i;
        }
        for(int i=1;i<=n;++i){
            string str;
            cin>>nodes[i].data;
            scanf("%d%d",&nodes[i].lchild,&nodes[i].rchild);
            father[nodes[i].lchild]=father[nodes[i].rchild]=i;
        }
        int root=findFather(1);
        inorder(root);
        return 0;
    }

    7-4 Dijkstra Sequence (30 分)

    我个人感觉这道题目出的比较好,dijkstra模板可能大家都理解了,那种固定的做题方式大家也都会,而这道题是考到了对模板的理解。

    刚开始我走了很多歪路,(主要是受之前做题惯性思维的影响,还在用dij+dfs之类的,当然也可以解,但不是很正的思路)

    思路:在dijkstra过程中,从所有优化好路径的点中取一个距离最小的点 u ,我们只需要判断所给出的例子中那一步的值可以不可取做u就可以了,若可以取则继续下一步判断,若不能取则直接判NO。能不能取做u的标准是,d[u]是不是当前的最小值之一。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <string>
    using namespace std;
    const int maxn=10010;
    const int inf=0x3fffffff;
    int nv,ne;
    struct node{
        int w,v;
    };
    vector<node>graph[maxn];
    int d[maxn];
    vector<int>check;
    bool vis[maxn];
    bool flag;
    int p;
    bool dijkstra2(int root){
        fill(d,d+maxn,inf);
        fill(vis,vis+maxn,false);
        d[root]=0;
        for(int i=1;i<=nv;++i){
            int MIN=inf,u=-1;
            for(int j=1;j<=nv;++j){//关键代码部分
                if(vis[j]==false&&d[j]<MIN){ //出现最小值让u取为它
                    MIN=d[j];
                    u=j;
                }
                else if(vis[j]==false&&d[j]==MIN){ //出现等于最小值,而且u是查询的值
                    if(j==check[p])u=j;
                }
            }
            if(u!=check[p]||u==-1)return false;
            vis[u]=true;
            p++;
            if(p>=nv)return true; //关键部分代码结束
            for(int j=0;j<graph[u].size();++j){
                int v=graph[u][j].v;
                if(vis[v]==false&&d[u]+graph[u][j].w<d[v]){
                    d[v]=d[u]+graph[u][j].w;
                }
            }
        }
    }
    
    int main(){
        cin>>nv>>ne;
        for(int i=0;i<ne;++i){
            int a,b,d;
            scanf("%d%d%d",&a,&b,&d);
            node temp;
            temp.v=b;
            temp.w=d;
            graph[a].push_back(temp);
            temp.v=a;
            graph[b].push_back(temp);
        }
        int k;
        cin>>k;
        for(int i=0;i<k;++i){
            check.clear();
            check.resize(nv);
            for(int j=0;j<nv;++j){
                scanf("%d",&check[j]);
            }
            flag=false;
            p=0;
            flag=dijkstra2(check[0]);
            if(flag)cout<<"Yes"<<endl;
            else{
                cout<<"No"<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    celery beat之pidfile already exists问题
    HBase源码系列之HFile
    吴裕雄--天生自然 JAVA开发学习:集合框架
    吴裕雄--天生自然 诗经:小池
    吴裕雄--天生自然 诗经:所见
    吴裕雄--天生自然 JAVA开发学习:数据结构
    吴裕雄--天生自然 JAVA开发学习:包(package)
    吴裕雄--天生自然 JAVA开发学习:接口
    吴裕雄--天生自然 JAVA开发学习:封装
    吴裕雄--天生自然 JAVA开发学习:抽象类
  • 原文地址:https://www.cnblogs.com/qujunhui/p/11490229.html
Copyright © 2020-2023  润新知