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\n",nodes[u].Address,nodes[u].Data,nodes[ans[i+1]].Address);
    }
    int u=ans[ans.size()-1];
    printf("%05d %d -1\n",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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM