PTA L2-002 链表去重 (25 分)
L2-002 链表去重 (25 分)
给定一个带整数键值的链表 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
用数组模拟链表
设置a数组用来存放值(value) b数组用来存放地址(next) 当前数组下标i表示当前地址
再用指针(int)来操作链表
最后注意输出地址时都要用%05d,输出-1时做特判
#include <bits/stdc++.h> using namespace std; const int N = 100005; int check[N]; //出现过的为1,没出现过的为0 int a[N], b[N]; // a[i]为值表,i为地址 a[i]为值; b[i]为地址表 i为地址,b[i]为next地址 int start; //起始地址 int n; //总结点数 int start2 = -1; //第二链表起始地址 void test() { cin >> start >> n; if (n == 0) { return; } int t; int p = start, pt, p1; //指针 for (int i = 1; i <= n; i++) { cin >> t; cin >> a[t] >> b[t]; //值 地址 } while (p != -1) { t = fabs(a[p]); if (check[t] == 0) { //第一次出现 check[t] = 1; //标记 pt = p; //记录p后一个位置 p = b[p]; //指向下一个 } else { //已出现过,设置到a2 b2中 if (start2 == -1) { //第一次 p1 = start2 = p; b[pt] = b[p]; b[p1] = -1; p = b[pt]; } else { b[pt] = b[p]; b[p1] = p; p1 = b[p1]; b[p1] = -1; p = b[pt]; } } } pt = start; while (pt != -1) { printf("%05d %d ", pt, a[pt]); if (b[pt] == -1) cout << -1 << endl; else printf("%05d\n", b[pt]); pt = b[pt]; } pt = start2; while (pt != -1) { printf("%05d %d ", pt, a[pt]); if (b[pt] == -1) cout << -1 << endl; else printf("%05d\n", b[pt]); pt = b[pt]; } } int main() { test(); return 0; }
题目链接:L2-002 链表去重 (25 分)