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;
}
原文地址:https://www.cnblogs.com/qujunhui/p/11490229.html