洛谷P1341《无序字母对》
原更新日期: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;
}