题目描述
给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
输入格式:
输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 −1 来表示。
随后 N 行,每行按以下格式描述一个结点:
地址 键值 下一个结点
其中
地址
是该结点的地址,键值
是绝对值不超过104的整数,下一个结点
是下个结点的地址。输出格式:
首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。
思路
1.vector存储链表, 输出时再输出下一个结点, 避免错误.
2.格式化输出(补0)
代码
#include <bits/stdc++.h>
#define PII pair<int, int>
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 300005;
using namespace std;
int val[N], ne[N], vis[N];
int head, n, id;
vector<int> l, del;
int main(){
cin >> head >> n;
while(n--){
cin >> id; //读入结点的值和下一个结点地址
cin >> val[id] >> ne[id];
}
while(head != -1){
if(vis[abs(val[head])])
del.push_back(head);
else
vis[abs(val[head])] = 1, l.push_back(head);
head = ne[head];
}
int sz1 = l.size(), sz2 = del.size();
for(int i = 0; i < sz1; i++){
int x = l[i]; //节点地址
printf("%05d %d ", x, val[x]);
if(i + 1 != sz1) //非末尾, 输出下一个结点值
printf("%05d\n", l[i + 1]);
else
cout << -1 << endl; //末尾
}
//同理
for(int i = 0; i < sz2; i++){
int x = del[i]; //节点地址
printf("%05d %d ", x, val[x]);
if(i + 1 != sz2) //非末尾, 输出下一个结点值
printf("%05d\n", del[i + 1]);
else
cout << -1; //末尾
}
}