zoukankan      html  css  js  c++  java
  • PAT 1097 Deduplication on a Linked List[比较]

    1097 Deduplication on a Linked List(25 分)

    Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the mean time, all the removed nodes must be kept in a separate list. For example, given L being 21→-15→-15→-7→15, you must output 21→-15→-7, and the removed list -15→15.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains the address of the first node, and a positive N (105​​) which is the total number of nodes. The address of a node is a 5-digit nonnegative integer, and NULL is represented by 1.

    Then N lines follow, each describes a node in the format:

    Address Key Next
    

    where Address is the position of the node, Key is an integer of which absolute value is no more than 104​​, and Next is the position of the next node.

    Output Specification:

    For each case, output the resulting linked list first, then the removed list. Each node occupies a line, and is printed in the same format as in the input.

    Sample Input:

    00100 5
    99999 -7 87654
    23854 -15 00000
    87654 15 -1
    00000 -15 99999
    00100 21 23854
    

    Sample Output:

    00100 21 23854
    23854 -15 99999
    99999 -7 -1
    00000 -15 87654
    87654 15 -1

     题目大意:给出一个链表,对重复的元素(绝对值相同的),只保留第一个出现的,并将所以其余的重复按顺序形成一个新链表。

     //问题1.这些数是整合成结构体的形式,还是存成单独的数组?2.怎么区分两个链表?

    代码来自:https://www.liuchuo.net/archives/2118

    #include <cstdio>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    const int maxn = 100000;
    struct NODE {
        int address, key, next, num = 2 * maxn;
    }node[maxn];
    bool exist[maxn];
    int cmp1(NODE a, NODE b){
        return a.num < b.num;
    }
    int main() {
        int begin, n, cnt1 = 0, cnt2 = 0, a;
        scanf("%d%d", &begin, &n);
        for(int i = 0; i < n; i++) {
            scanf("%d", &a);
            scanf("%d%d", &node[a].key, &node[a].next);
            node[a].address = a;//将所有的点保存。
        }
        for(int i = begin; i != -1; i = node[i].next) {
            if(exist[abs(node[i].key)] == false) {
                exist[abs(node[i].key)] = true;
                node[i].num = cnt1;
                cnt1++;//通过这个来计数,厉害了啦!解决了链表的顺序问题。
            }
            else {
                node[i].num = maxn + cnt2;
                cnt2++;//对重复的计数。
            }
        }
        sort(node, node + maxn, cmp1);//使用sort排序之后,就没有地址下下标的区分了。
        //这样排序之后保证了重复的排在后面,同时也保证了链表的顺序。
        int cnt = cnt1 + cnt2;
        for(int i = 0; i < cnt; i++) {
            if(i != cnt1 - 1 && i != cnt - 1) {//这两个涵盖的情况是正常链最后一个,和非正常链最后一个
                printf("%05d %d %05d\n", node[i].address, node[i].key, node[i+1].address);
            } else {
                printf("%05d %d -1\n", node[i].address, node[i].key);
            }
        }
        return 0;
    }

    //感觉超厉害,我实在是想不出这种办法,学习了!

    https://blog.csdn.net/realxuejin/article/details/49362519  

    这位大佬使用向量存储,很受启发,今天晚上写一下。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #include<algorithm>
    using namespace std;
    struct Node{
        int addr,num,next;
    }node[100000];
    int flag[10000];
    int main()
    {
        int head,n;
        scanf("%d %d",&head,&n);
        int a;
        vector<Node> v1,v2;//分别存储正常和重复的两个链表。
        for(int i=0;i<n;i++){
            scanf("%d",&a);
            scanf("%d %d",&node[a].num,&node[a].next);
            node[a].addr=a;//这里一定要将所有的节点都保存,然后再进行操作,因为直接操作可能有无用的点扰乱。
        }
        if(node[head].addr==-1){
            cout<<'\n';return 0;
        }
        for(int i=head;i!=-1;i=node[i].next){
            if(flag[abs(node[i].num)]==0){
                flag[abs(node[i].num)]=1;
                v1.push_back(node[i]);//
            }else
                v2.push_back(node[i]);
        }
        for(int i=0;i<v1.size();i++){
            if(i!=v1.size()-1)
                printf("%05d %d %05d\n",v1[i].addr,v1[i].num,v1[i+1].addr);
            else
                printf("%05d %d -1\n",v1[i].addr,v1[i].num);
        }
        if(v2.size()==0)return 0;
        for(int i=0;i<v2.size();i++){
            if(i!=v2.size()-1)
                printf("%05d %d %05d\n",v2[i].addr,v2[i].num,v2[i+1].addr);
            else
                printf("%05d %d -1\n",v2[i].addr,v2[i].num);
        }
    
        return 0;
    }
    /**
    -1 0
    
    1 2
    1 2 3
    3 1 -1
    **/
    View Code

    //这是我写的代码,测试点3通不过,

    #include <iostream>
    #include <vector>
    #include <cmath>
    #include<stdio.h>
    using namespace std;
    
    struct node{
        int addr;
        int key;
        int next;
    };
    
    int main(int argc, char** argv) {
        int root, n, i;
        scanf("%d%d",&root, &n);
        vector<node> list(100000);
    
        int addr, key, next;
        for(i=0; i<n; i++){
            scanf("%d %d %d",&addr,&key,&next);
            list[addr].key = key;
            list[addr].next = next;
            list[addr].addr = addr;
        }
    
        if(list[root].addr == -1){
            cout<<endl;
            return 0;
        }
    
        vector<int> flag(10001,-1);
        vector<node> cut; //存放因为重复而被删掉的节点
        vector<node> vec;
        int index = root;
        while( index != -1){
            key = abs(list[index].key);
            if(flag[key] == -1){
                flag[key] = 1;
                vec.push_back(list[index]);
            }else{
                cut.push_back(list[index]);
            }
            index = list[index].next;
        }
    
        node Node;
        for(i=0; i<vec.size()-1; i++){
            Node = vec[i];
            printf("%05d %d %05d\n", Node.addr, Node.key, vec[i+1].addr );
        }
        Node = vec[vec.size()-1];
        printf("%05d %d -1\n", Node.addr, Node.key );
    
        //没有重复的情况下
         if(cut.size() == 0)
             return 0;
        for(i=0; i<cut.size()-1; i++){
            Node = cut[i];
            printf("%05d %d %05d\n", Node.addr, Node.key, cut[i+1].addr );
        }
        Node = cut[cut.size()-1];
        printf("%05d %d -1\n", Node.addr, Node.key );
    
        return 0;
    }

    //大佬的代码可以通过,我感觉我们的都一样啊 ,为什么通不过呢。。。明天再看一下,好气啊。

  • 相关阅读:
    冯小刚贺岁片十大经典台词
    网络”X客”大集合:博客、维客、奇客、播客、闪客、摩客、威克…
    [ASP.NET]动态页面调用JS错误。保存为HTML文件就不报错了。
    xp sp2 pro 安装IIS时候出现 安装程序无法复制文件staxmem.dl_
    上传功能出现 asp 0104 不允许操作解决方法
    插入数据库记录时候“输入字符串的格式不正确。 ”
    猪的FLASH-星晴
    Tab Bar Controller 与 Navigation Controller 共存
    iPhone控件之UILabel
    使用MPMoviePlayerViewController播放视频
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9511752.html
Copyright © 2011-2022 走看看