您的位置:首页 > 其它

洛谷P1341 无序字母对

2016-08-20 17:31 369 查看

P1341 无序字母对

229通过

806提交

题目提供者yeszy

标签图论福建省历届夏令营

难度提高+/省选-

提交该题 讨论 题解 记录

最新讨论

不知道哪里错

求解释

题目描述

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

输入输出格式

输入格式:

第一行输入一个正整数n。

以下n行每行两个字母,表示这两个字母需要相邻。

输出格式:

输出满足要求的字符串。

如果没有满足要求的字符串,请输出“No Solution”。

如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

输入输出样例

输入样例#1:

4
aZ
tZ
Xt
aX


输出样例#1:

XaZtX


说明

【数据规模与约定】

不同的无序字母对个数有限,n的规模可以通过计算得到。

分析:因为字母对的字母可以交换,所以我们可以想象成将n个字母对通过某种变换连成一起然后一次走到通.而n个字母对,n+1个字母组成字符串,说明每个字符都必须要在字符串中出现,也就是说选定一个起点,要在两个串之间的公共部分走到终点,而且n+1个字母不允许我们重复走,所以很容易联想到欧拉道路.那么我们建图,每一个字母对之间的字母连一条无向边,一个字母当作一个顶点,每连一条边,则两点的度数+1,如果度数为奇数的点只有两个或没有,那么就存在欧拉道路,那么利用dfs就可以求出.题目还有一个要求就是字典序最小,显然如果度数为奇数的点为两个,那么这两个点要么就是起点或终点,因为是无向图,所以不管是从起点出发还是从终点出发都是一样的,所以选择字典序小的一遍出发即可,那么度数为奇数的点没有呢?很简单,从任何一个点出发即可.比较坑的一点就是数据范围还要我们计算......

#include <cstdio>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 100;
int map[maxn][maxn], cnt[maxn], vis[maxn][maxn];
int n, maxm = 53;
stack <int> ans;

int zhuanhua1(char c)
{
if (c >= 'A' && c <= 'Z')
return (int)c - 'A';
return (int)c - 'a' + 26;
}

char zhuanhuan2(int x)
{
if (x >= 0 && x <= 25)
return (char)x + 'A';
return (char)(x - 26) + 'a';
}

void euler(int u)
{
for (int v = 0; v < maxm; v++)
if (map[u][v] && !vis[u][v])
{
vis[u][v] = vis[v][u] = 1;
euler(v);
ans.push(v);
}
}

int main()
{
scanf("%d%d", &n);
for (int i = 1; i <= n; i++)
{
char a, b;
cin >> a >> b;
int x = zhuanhua1(a), y = zhuanhua1(b);
map[x][y] = map[y][x] = 1;
cnt[x]++;
cnt[y]++;
}
int tot = 0, min1 = 1e8, min2 = 1e8;
for (int i = 0; i < maxm; i++)
{
if (cnt[i] & 1)
{
tot++;
min1 = min(min1, i);
}
else if (cnt[i])
min2 = min(min2, i);
}
if (tot != 0 && tot != 2)
printf("No Solution\n");
else
{
int u;
if (tot == 0)
u = min2;
else
u = min1;
euler(u);
ans.push(u);
while (!ans.empty())
{
int temp = ans.top();
ans.pop();
char s = zhuanhuan2(temp);
cout << s;
}
printf("\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: