洛谷P1341《無序字母對》
阿新 • • 發佈:2020-10-14
原更新日期:2019-01-21 17:11:55
尤拉圖板子題
題目描述
給定n個各不相同的無序字母對(區分大小寫,無序即字母對中的兩個字母可以位置顛倒)。請構造一個有n+1個字母的字串使得每個字母對都在這個字串中出現。
輸入輸出格式
輸入格式
第一行輸入一個正整數n。
以下n行每行兩個字母,表示這兩個字母需要相鄰。
輸出格式
輸出滿足要求的字串。
如果沒有滿足要求的字串,請輸出“No Solution”。
如果有多種方案,請輸出前面的字母的ASCII編碼儘可能小的(字典序最小)的方案
輸入輸出樣例
輸入樣例
4
aZ
tZ
Xt
aX
輸出樣例
XaZtX
說明
【資料規模與約定】
不同的無序字母對個數有限,n的規模可以通過計算得到。
解題思路
我們考慮把每一對字母視為一條邊
那麼這個圖就是無向的(因為字母對是無序的)
題目讓你求一個串,使得這個串裡出現了所有的字母對,實際上就是讓你求一條路徑,使得所有的邊都出現過
那這不就是求尤拉路嗎!
所以這道題就完美地被轉換為了尤拉路板子題
沒學過尤拉路的看這裡
程式碼實現
/* -- Basic Headers -- */ #include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <algorithm> /* -- STL Iterators -- */ #include <vector> #include <string> #include <stack> #include <queue> /* -- External Headers -- */ #include <map> #include <cmath> /* -- Defined Functions -- */ #define For(a,x,y) for (int a = x; a <= y; ++a) #define Forw(a,x,y) for (int a = x; a < y; ++a) #define Bak(a,y,x) for (int a = y; a >= x; --a) namespace FastIO { inline int getint() { int s = 0, x = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') x = -1; ch = getchar(); } while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); } return s * x; } inline void __basic_putint(int x) { if (x < 0) { x = -x; putchar('-'); } if (x >= 10) __basic_putint(x / 10); putchar(x % 10 + '0'); } inline void putint(int x, char external) { __basic_putint(x); putchar(external); } } namespace Solution { const int MAXN = 256 + 233; int n; int G[MAXN][MAXN], deg[MAXN]; char __MIN_NODE = 127, __MAX_NODE = 0; std::stack<char> stk; inline void addEdge(char prev, char next, bool Undirected = true) { ++G[prev][next]; if (Undirected) addEdge(next, prev, false); } inline void deleteEdge(char prev, char next, bool Undirected = true) { --G[prev][next]; if (Undirected) deleteEdge(next, prev, false); } inline void Hierholzer(char s) { for (char i = __MIN_NODE; i <= __MAX_NODE; ++i) { if (G[s][i]) { deleteEdge(s, i); Hierholzer(i); } } stk.push(s); } } signed main() { #define HANDWER_FILE #ifndef HANDWER_FILE freopen("testdata.in", "r", stdin); freopen("testdata.out", "w", stdout); #endif using namespace Solution; std::ios::sync_with_stdio(false); std::cin >> n; For (i, 1, n) { char prev, next; std::cin >> prev; std::cin >> next; addEdge(prev, next); ++deg[prev]; ++deg[next]; __MIN_NODE = std::min(__MIN_NODE, std::min(prev, next)); __MAX_NODE = std::max(__MAX_NODE, std::max(prev, next)); } int odd = 0; char start = 0; for (char i = __MIN_NODE; i <= __MAX_NODE; ++i) { if (deg[i] != 0 && deg[i] % 2 == 1) { if (!start) start = i; ++odd; } } if (!start) start = __MIN_NODE; if (odd && odd != 2) { // 注意不要忘了判無解 std::cout << "No Solution" << std::endl; return 0; } Hierholzer(start); while (!stk.empty()) { std::cout << stk.top(); stk.pop(); } return 0; }