zoukankan      html  css  js  c++  java
  • 天梯赛 L2-002. (模拟) 链表去重

    题目链接

    题目描述
    给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的结点。即对任意键值K,只有键值或其绝对值等于K的第一个结点可以被保留。同时,所有被删除的结点必须被保存在另外一个链表中。例如:另L为21→-15→-15→-7→15,则你必须输出去重后的链表21→-15→-7、以及被删除的链表-15→15。

    输入格式:

    输入第一行包含链表第一个结点的地址、以及结点个数N(<= 105 的正整数)。结点地址是一个非负的5位整数,NULL指针用-1表示。

    随后N行,每行按下列格式给出一个结点的信息:

    Address Key Next

    其中Address是结点的地址,Key是绝对值不超过104的整数,Next是下一个结点的地址。

    输出格式:

    首先输出去重后的链表,然后输出被删除结点组成的链表。每个结点占一行,按输入的格式输出。

    输入样例:
    00100 5
    99999 -7 87654
    23854 -15 00000
    87654 15 -1
    00000 -15 99999
    00100 21 23854

    输出样例:
    00100 21 23854
    23854 -15 99999
    99999 -7 -1
    00000 -15 87654
    87654 15 -1

    分析:
    说的是链表的去重,但是并不能采用链表来做,用数组来模拟链表。
    因为存储的信息不仅仅是一个,所以采用结构体来保存一个节点的信息,在进行去重的时候,额外的需要一个标记数组来记录当前这个结点的key值或者key值的绝对值有没有出现过,如果没有出现过的话,就将这个节点加入到去重后的数组中,如果出现过的话,就将这个结点加入到需要删除的数组中,当然无论加入到那个数组中,这个结点的key值的绝对值都应该被标记。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <stack>
    using namespace std;
    const int maxn=1e5+5;
    struct node//结构体保存最原始的链表信息,用下标来表示结点的地址
    {
        int key,next;//结点值和下一个结点的地址
    } node[maxn];
    struct Newnode//表示新的去重后的链表和被删除的节点的链表
    {
        int address,key;//节点的地址和值
    } New[maxn],dele[maxn];
    int vis[maxn];
    int main()
    {
        int star,n;
        scanf("%d%d",&star,&n);
        int add;
        memset(vis,0,sizeof(vis));
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&add);
            scanf("%d%d",&node[add].key,&node[add].next);
        }
        int last=star;
        int cnt1=0,cnt2=0;
        for(int i=star; i!=-1; i=node[i].next)
        {
            int k=fabs(node[i].key);
            if(vis[k]==0)//这个数没有出现过,那么这个结点可以加入到去重后的链表中
            {
                vis[k]=1;
                New[cnt1].key=node[i].key;
                New[cnt1].address=i;
                cnt1++;
            }
            else//这个值或者它的绝对值已经出现过了,那么他就应该加入到删除结点的链表中
            {
                vis[k]=1;
                dele[cnt2].key=node[i].key;
                dele[cnt2].address=i;
                cnt2++;
            }
        }
        for(int i=0; i<cnt1; i++)
        {
            printf("%05d %d ",New[i].address,New[i].key);
            if(i==cnt1-1)//最后一个结点的下地址为-1,标记着链表结束
                printf("-1
    ");
            else
                printf("%05d
    ",New[i+1].address);//否则的话下地址应该是下一个结点的地址
        }
        //同上
        for(int i=0; i<cnt2; i++)
        {
            printf("%05d %d ",dele[i].address,dele[i].key);
            if(i==cnt2-1)
                printf("-1
    ");
            else
                printf("%05d
    ",dele[i+1].address);
        }
        return 0;
    }
    
  • 相关阅读:
    蛋白质修饰|phosphors|mascot+X|
    miRNA|housekeeping|RNAi|siRNA|Oncomirs|miRBase|PMRD|TargetScan|miRDeep|miRNA target|seed regions|
    期刊|二次文摘数据库
    ISBN|方正|超星|The national academies press|OECD|RSC|Springer Link|Knovel|Encyclopedia Britannica
    CSA|EI
    材料和方法|详略得当
    撰写introduction|引用
    无聊期,就是最好的增值期
    swift中为什么要创造出可选型?
    win7连接无线网出现黄色感叹号怎么办?
  • 原文地址:https://www.cnblogs.com/cmmdc/p/8582771.html
Copyright © 2011-2022 走看看