1. 程式人生 > 其它 >PTA L2-002 連結串列去重 (25 分)

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 分)