pat 团体天梯赛 L2-002. 链表去重

L2-002. 链表去重

时间限制
300 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

给定一个带整数键值的单链表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

思路:
模拟,过程可以这样思考:建立两个链表,链表1是去重后的链表,链表2是被删除节点组成的链表,对于原链表的每个节点,判断当前节点的值是否出现过,若出现过,连同节点的地址接在链表2上,否则接在链表1上。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring> 
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define INF 0x3f
#define EPS 1e-5
#define pi cos(-1)
const int N_MAX = 100000+15;
int n;
int root;
bool vis[N_MAX];
struct Node {
    int Adress, Next;
    int key;
    Node() {}
    Node(int Adress,int Key,int Next):Adress(Adress),key(Key),Next(Next) {}
};
map<int, Node>node;
Node remain[N_MAX], cut[N_MAX];
int main() {
    while (scanf("%d%d",&root,&n)!=EOF) {
        memset(vis, 0, sizeof(vis));
        bool flag = 1;
        for (int i = 0; i < n; i++) {
            int Adress, Next,key;                    
            scanf("%d%d%d",&Adress,&key,&Next);
            node.insert(make_pair(Adress, Node(Adress, key, Next)));
        }
        
        int r = root;
        int num1 = 0, num2 = 0;//
        while(r!=-1) {//!!!!!
            if (vis[abs(node[r].key)] == false) {//没找到这个数的记录
                remain[num1] = (Node(node[r].Adress, node[r].key, -1));//Next指针暂时不知道
                if (num1 != 0) {
                    remain[num1 - 1].Next = node[r].Adress;
                }
                vis[abs(node[r].key)] = true;
                num1++;
            }
            else {
                cut[num2] = (Node(node[r].Adress, node[r].key,-1));//Next指针暂时不知道
                if (num2 != 0) {//不是第一个重复数字
                    cut[num2 - 1].Next = node[r].Adress;
                }
                num2++;
            }
            r = node[r].Next;
        }
        for (int i = 0; i < num1; i++) {
            if(i+1!=num1)printf("%05d %d %05d
", remain[i].Adress, remain[i].key, remain[i].Next);
            else printf("%05d %d %d
", remain[i].Adress, remain[i].key, remain[i].Next);
        }
        for (int i = 0; i < num2; i++) {
            if (i + 1 != num2)printf("%05d %d %05d
", cut[i].Adress, cut[i].key, cut[i].Next);
            else printf("%05d %d %d
", cut[i].Adress, cut[i].key, cut[i].Next);
        }
        node.clear();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ZefengYao/p/8066741.html