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;
    }

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

  • 相关阅读:
    UVa 10088 (Pick定理) Trees on My Island
    LA 3295 (计数 容斥原理) Counting Triangles
    LA 5846 (计数) Neon Sign
    java是什么?软帝学院告诉你学Java能做什么?Java有什么特性?
    【软帝学院】一套好的java基础教学视频需要哪些有哪些内容
    推荐五个java基础学习网站,小白必备
    学习java设计模式有用吗?懂这六个原则,编程更轻松
    Java是什么?只需5分钟,了解java必须要知道的知识点
    软帝学院:自学java到底难不难?做好这几步,少走3年弯路
    软帝学院:java开发程序很难吗?学会这十步,5分钟搞定一个程序
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9511752.html
Copyright © 2011-2022 走看看