「CodeForces」847A Union of Doubly Linked Lists
阿新 • • 發佈:2021-07-08
小兔的話
歡迎大家在評論區留言哦~
簡單題意
給定 \(n(n \leq 100)\) 個數的前驅和後繼,但其中有些數沒有前驅或者沒有後繼,其相應的值為 \(0\)
請在原有資訊的基礎上構造出一個新連結串列,輸出每個數的前驅和後繼
新連結串列應該滿足的條件:只有一個數沒有前驅,其為起點;只有一個數沒有後繼,其為終點
解析
根據輸入給出的資訊,從沒有前驅的數開始向後搜尋,直到沒有後繼為止
這樣可以求出一些子連結串列,再把這些子連結串列連線就可以了
這裡用樣例舉例:
4 7
5 0
0 0
6 1
0 2
0 4
1 0
分析樣例,可以得出一下連結串列:
3
5-2
6-4-1-7
連線之後:
3 - 5-2 - 6-4-1-7 3-5-2-6-4-1-7
最後得出:
4 7
5 6
0 5
6 1
3 2
2 4
1 0
程式碼(純陣列)
#include <cstdio> int rint() { int x = 0, fx = 1; char c = getchar(); while (c < '0' || c > '9') { fx ^= (c == '-'); c = getchar(); } while ('0' <= c && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = getchar(); } if (!fx) return -x; return x; } const int MAX_n = 100; int n, now; int u[MAX_n + 5]; // 前驅 int v[MAX_n + 5]; // 後繼 int main() { n = rint(); for (int i = 1; i <= n; i++) u[i] = rint(), v[i] = rint(); for (int i = 1; i <= n; i++) { if (u[i] == 0) // 沒有前驅的肯定是一條子連結串列的起點 { v[now] = i; u[i] = now; now = i; // 與上一條子連結串列相連 while (v[now]) now = v[now]; // 向後搜尋 // 迴圈結束, 找到當前子連結串列的終點 } } for (int i = 1; i <= n; i++) printf("%d %d\n", u[i], v[i]); return 0; }
程式碼(vector)
#include <cstdio> #include <vector> using namespace std; int rint() { int x = 0, fx = 1; char c = getchar(); while (c < '0' || c > '9') { fx ^= (c == '-'); c = getchar(); } while ('0' <= c && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = getchar(); } if (!fx) return -x; return x; } const int MAX_n = 100; int n; int u[MAX_n + 5]; // 前驅 int v[MAX_n + 5]; // 後繼 vector<pair<int, int> > e; // pair 記錄每條子連結串列的頭和尾 int DFS(int now) { if (v[now] == 0) return now; // 返回終點 return DFS(v[now]); // 向後搜尋 } int main() { n = rint(); for (int i = 1; i <= n; i++) { u[i] = rint(); v[i] = rint(); } for (int i = 1; i <= n; i++) if (u[i] == 0) e.push_back(make_pair(i, DFS(i))); // 插入當前子連結串列 (簡化版, 只留頭和尾, 中間的沒有影響) int siz = e.size(); for (int i = 1; i < siz; i++) { v[e[i - 1].second] = e[i].first; u[e[i].first] = e[i - 1].second; // 每條子連結串列與前一個子連結串列相連 } for (int i = 1; i <= n; i++) printf("%d %d\n", u[i], v[i]); return 0; }