給定一個帶整數鍵值的鏈表 L,你需要把其中絕對值重複的鍵值結點刪掉。即對每個鍵值 K,只有第一個絕對值等於 K 的結點被保留。同時,所有被刪除的結點須被保存在另一個鏈表上。例如給定 L 爲 21→-15→-15→-7→15,你需要輸出去重後的鏈表 21→-15→-7,還有被刪除的鏈表 -15→15。
輸入格式:
輸入在第一行給出 L 的第一個結點的地址和一個正整數 N(≤105,爲結點總數)。一個結點的地址是非負的 5 位整數,空地址 NULL 用 -1 來表示。
隨後 N 行,每行按以下格式描述一個結點:
地址 鍵值 下一個結點
其中地址
是該結點的地址,鍵值
是絕對值不超過104的整數,下一個結點
是下個結點的地址。
輸出格式:
首先輸出去重後的鏈表,然後輸出被刪除的鏈表。每個結點佔一行,按輸入的格式輸出。
輸入樣例:
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
node保存了節點的基本信息,當前地址now, 節點的值val, 下一個地址next, nodes[i]則存儲地址i下的一個完整節點信息。
用next0保存節點的鏈式關係,遍歷整條鏈,將val絕對值相同的篩選出來,這樣得到兩條鏈。
爲了打印的時候重新建立鏈式關係,在打印v[i].next時,實際上每次打印的是容器中下一個元素的now,即v[i + 1].now,另外就是最後一個節點的next要設成-1。
#include<iostream>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 1e6 + 10;
int vis[maxn], next0[maxn];
struct node {
int now, val, next;
} nodes[maxn];
void print(vector<node> &v) {
for (int i = 0; i < v.size(); i++) {
printf("%05d %d ", v[i].now, v[i].val);
if (i + 1 < v.size()) printf("%05d", v[i + 1].now);
else printf("-1");
if (i < v.size() - 1) printf("\n");
}
}
int main() {
vector<node> v;
int head, num;
cin >> head >> num;
while (num--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
next0[a] = c;
nodes[a] = node {a, b, c};
}
vector<node> v1, v2;
for (int i = head; i != -1; i = next0[i]) {
if (!vis[abs(nodes[i].val)]) {
v1.push_back(nodes[i]);
vis[abs(nodes[i].val)] = 1;
} else {
v2.push_back(nodes[i]);
}
}
print(v1);
printf("\n");
print(v2);
return 0;
}