PAT链表题汇总 1032 1074 1097 1133

PAT的链表题还算比较友好 ,大多用静态链表

PAT 1032 Sharing

在储存单词时,我们可以使用链表逐个字母进行储存。

为了节约空间,如果两个单词拥有共同的后缀,那么可以让它们共享一个相同的子链表。

例如,loading 和 being 可以如下图所示储存:

PAT链表题汇总 1032 1074 1097 1133_第1张图片

你需要找到共同后缀的起始位置。(对于上图,即为 ii 的位置)

 

#include
#define rep(i,a,n) for(int i=a;i>head>>head1>>n;
    rep(i,0,n){
        int id;
        cin>>id;
        cin>>a[id].data>>a[id].next;
    }
    int p=head;
    while(p!=-1){
        vis[p]=1;
        p=a[p].next;
    }
    p=head1;
    while(p!=-1){
        if(vis[p]) {
            printf("%05d",p);
            return 0;
        }
        p=a[p].next;
    }
    puts("-1");
}

PAT1074 Reversing Linked List 反转链表

给定一个常数 KK 和一个单链表 LL,请你在单链表上每 K个元素做一次反转,并输出反转完成后的链表。

例如,假设 LL 为 1→2→3→4→5→6,如果 K=3,则你应该输出 3→2→1→6→5→4;如果 K=4,则你应该输出 4→3→2→1→5→6

补充

1、本题中可能包含不在链表中的节点,这些节点无需考虑。

#include
#define rep(i,a,n) for(int i=a;i>head>>n>>k;
    rep(i,0,n){
        int id;
        cin>>id;
        cin>>a[id].data>>a[id].next;
    }
    int cnt=0;
    int p=head;
    while(p!=-1){
        L[cnt++]=p;
        p=a[p].next;
    }
    rep(i,0,cnt) ans[i]=L[i];
    rep(i,0,cnt/k){
        rep(j,0,k)
            ans[i*k+j]=L[i*k+k-1-j];
    }
    rep(i,0,cnt-1)
        printf("%05d %d %05d\n",ans[i],a[ans[i]].data,ans[i+1]);
    printf("%05d %d -1\n",ans[cnt-1],a[ans[cnt-1]].data);    
}

 

PAT 1097 Deduplication on a Linked List 链表重复数据删除 

给定一个单链表 L,链表上的每个节点都存有一个键值,你应该删掉其中拥有重复键值绝对值的节点。

也就是说,对于每个值 K,只保留键值或键值绝对值为 K 的第一个节点。

同时,被删掉的节点也应保存在一个单独的链表中。

例如,给定 L 为 21→-15→-15→-7→15,则删除重复数据后的链表为 21→-15→-7,已删除链表为 -15→15

#include
#define rep(i,a,n) for(int i=a;i>head>>n;
    rep(i,0,n){
        int id;
        cin>>id;
        cin>>a[id].data>>a[id].next;
    }
    int cnt=0,tot=0;
    int p=head;
    while(p!=-1){
        int t=fabs(a[p].data);
        if(!vis[t]){
            vis[t]=1;
            L[cnt++]=p;
        }
        else{
            del[tot++]=p;
        }
        p=a[p].next;
    }
    rep(i,0,cnt-1)
        printf("%05d %d %05d\n",L[i],a[L[i]].data,L[i+1]);
    printf("%05d %d -1\n",L[cnt-1],a[L[cnt-1]].data);
    if(tot){
        rep(i,0,tot-1)
            printf("%05d %d %05d\n",del[i],a[del[i]].data,del[i+1]);
        printf("%05d %d -1\n",del[tot-1],a[del[tot-1]].data);    
    }
}

PAT1133 Splitting A Linked List 链表元素分类

给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0,K][0,K] 区间内的元素都排在大于 K 的元素前面。

但每一类内部元素的顺序是不能改变的。

例如:给定链表为 18→7→-4→0→5→-6→10→11→-2,K 为 10,则输出应该为 -4→-6→-2→7→0→5→10→18→11

 

#include
#define rep(i,a,n) for(int i=a;i>head>>n>>k;
    rep(i,0,n){
        int id;
        cin>>id;
        cin>>a[id].data>>a[id].next;
    }
    int cnt[4]={0};
    int p=head;
    while(p!=-1){
        int t=a[p].data;
        if(t<0){
            L[1][cnt[1]++]=p;
        }
        else if(t<=k)
            L[2][cnt[2]++]=p;
        else 
            L[3][cnt[3]++]=p;
        p=a[p].next;
    }
    vectorans;
    rep(i,1,4)
        rep(j,0,cnt[i]) 
            ans.push_back(L[i][j]);
    rep(i,0,ans.size()-1){
        printf("%05d %d %05d\n",ans[i],a[ans[i]].data,ans[i+1]);
    }
    printf("%05d %d -1\n",ans[ans.size()-1],a[ans[ans.size()-1]].data);
    
}

 

你可能感兴趣的:(PTA,其他)