题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

输出满足要求的字符串。

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

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

输入输出样例

输入样例#1:
复制

4
aZ
tZ
Xt
aX
输出样例#1: 复制

XaZtX
 

说明

【数据规模与约定】

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


题解

首先翻译一下题面吧。

给定n条无向边,试构造一条路径恰好经过每条边1次。

如果可以构造,输出途径的点的编号。

否则输出No Solution。

其实想明白所谓的字母对只是无向边的话,这道题就是很清晰的欧拉路径了。

——以下来自欧拉回路路径求解 - STILLxjy - CSDN博客——

Hierholzer 算法:
另一种计算欧拉路的算法是 Hierholzer 算法。这种算法是基于这样的观察:

在手动寻找欧拉路的时候,我们从点 4 开始,一笔划到达了点 5,形成路径 4-5-2-3-6-5。此时我们把这条路径去掉,则剩下三条边,2-4-1-2 可以一笔画出。

这两条路径在点 2 有交接处(其实点 4 也是一样的)。那么我们可以在一笔画出红色轨迹到达点 2 的时候,一笔画出黄色轨迹,再回到点 2,把剩下的红色轨迹画完。

由于明显的出栈入栈过程,这个算法可以用 DFS 来描述。
如果想看得更仔细一点,下面是从点 4 开始到点 5 结束的 DFS 过程,其中 + 代表入栈,- 代表出栈。
4+ 5+ 2+ 3+ 6+ 5+ 5- 6- 3- 1+ 4+ 2+ 2- 4- 1- 2- 5- 4-
我们把所有出栈的记录连接起来,得到
5-6-3-2-4-1-2-5-4

诸位看官可以自己再选一条路径尝试一下。不过需要注意的是,起始点的选择和 Fleury 要求的一样。
这个算法明显要比 Fleury 高效,它不用判断每条边是否是一个桥。

Hierholzer的复杂度是$O(E)$的,所以就套欧拉路径的板子就好啦。

(实在没懂怎么“计算得到”n的规模,好在不用这个条件QAQ

 /*
qwerta
P1341 无序字母对
Accepted
100
代码 C++,1.46KB
提交时间 2018-09-30 11:11:47
耗时/内存
28ms, 1052KB
*/
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
int g[][];
int d[];//度数
stack<int>st;//这个是记录栈,不是搜索栈!
void dfs(int x)//dfs找点
{
for(int j='A';j<='z';++j)//这样循环就可以保持字典序最小啦
if(g[x][j])
{
g[x][j]--;
g[j][x]--;//反向边也要删
dfs(j);//继续递归
}
st.push(x);//出栈的时候记录下来
return;
}
int fa[];//用并查集维护是否有多个联通块
int fifa(int x)
{
if(fa[x]==x)return x;
return fa[x]=fifa(fa[x]);
}
int main()
{
//freopen("a.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(false),cout.tie(false);//关闭同步流(cin伴侣
int n;
cin>>n;
for(int i='A';i<='z';++i)//初始化并查集
fa[i]=i;
for(int i=;i<=n;++i)
{
char x,y;
cin>>x>>y;
g[x][y]++;
g[y][x]++;//临接矩阵存边
d[x]++;
d[y]++;//度数++
int u=fifa(x),v=fifa(y);
if(u!=v)fa[u]=v;//维护并查集
}
//判定是否有解
int num=;
for(int i='A';i<='z';++i)
if(d[i]%==)num++;
if(num!=&&num!=){cout<<"No Solution";return ;}
int tag=;
for(int i='A';i<='z';++i)
if(d[i])
{
if(!tag)tag=i;
else if(fifa(tag)!=fifa(i)){cout<<"No Solution";return ;}
}
//找是否有奇点
int s=-;
for(int i='A';i<='z';++i)
if(d[i]%==){s=i;break;}
if(s==-)//如果没有奇点就找AscII最小的点
for(int i='A';i<='z';++i)
if(d[i]){s=i;break;}
dfs(s);//递归找点
while(!st.empty())
{
cout<<(char)st.top();
st.pop();
}//输出
return ;
}

皮一下:

「LuoguP1341」 无序字母对(欧拉回路的更多相关文章

  1. P1341 无序字母对 欧拉回路

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...

  2. [Luogu1341]无序字母对(欧拉回路)

    按题意给定字符串建无向图,找欧拉回路 按照定义,当没有奇数度点或者只有2个奇数度点时才有欧拉回路 Code #include <cstdio> #include <algorithm ...

  3. 洛谷 P1341 无序字母对(欧拉回路)

    题目传送门 解题思路: 一道欧拉回路的模板题,详细定理见大佬博客,任意门 AC代码: #include<cstdio> #include<iostream> using nam ...

  4. [luogu1341]无序字母对【欧拉回路】

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 分析 欧拉回路的模板题. 暴力删边欧拉 ...

  5. 洛谷P1341 无序字母对(欧拉回路)

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

  6. P1341 无序字母对(欧拉回路)

    题目链接: https://www.luogu.org/problemnew/show/P1341 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一 ...

  7. 「 深入浅出 」集合Set

    系列文章 「 深入浅出 」集合List 「 深入浅出 」java集合Collection和Map Set继承自Collection接口,不能包含有重复元素.本篇文章主要讲Set中三个比较重要的实现类: ...

  8. 「CometOJ」Contest #11

    Link Aeon 显然字典序最大就是把最小的字母放在最后 Business [动态规划] 简单dp dp[i][j]dp[i][j]dp[i][j]表示到第iii天,当前有jjj块钱,最后返还的钱最 ...

  9. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

随机推荐

  1. 偏执的iOS逆向研究员:收集全版本的macOS iOS+越狱+内核调试

    Intro 虽然“只有偏执狂才能够生存”这句话已经被假药停给毁了,但是作为一只有逼格的高大上的iOS逆向分析研究员,难道如果有现成的macOS/iOS全版本镜像可以下载并且无限“漫游”,难道你就不想来 ...

  2. Direct2D教程(三)简单几何图形

    从本章开始,我们介绍D2D几何图形. D2D图形分类 Direct2D支持多种类型的几何图形,包括Simple Geometry(简单几何图形) 矩形 圆角矩形 椭圆 Path Geometry(路径 ...

  3. yii框架:CDbConnection failed to open the DB connection: could not find driver的解决的方法

    这个问题是由于php中缺少pdo mysql造成的. 解决方法是为php加入此扩展.前往你最早的php安装文件,进入ext/pdo_mysql/文件夹下,然后./configure --with-ph ...

  4. Ural 2018The Debut Album(DP)

    题目地址:Ural 2018 简单DP.用滚动数组. 代码例如以下: #include <iostream> #include <cstdio> #include <st ...

  5. Android二维码工具zxing使用

    二维码在我们生活中随处可见.在我眼里简直能够用"泛滥"来形容啦.那怎样在我们Android项目中扫描识别二维码或生成二维码图片呢? 我们通常使用的开源框架是zxing.在githu ...

  6. android相关文件夹的存取方式与函数解析---全

    因为排版问题.转为markdown编辑: http://blog.csdn.net/self_study/article/details/58587412

  7. MySQL windows集群(转)

    http://blog.csdn.net/zhangking/article/details/5670070    MySQL 群集是 MySQL 适合于分布式计算环境的高可用.高冗余版本.它采用了 ...

  8. 转载---- 使用opencv源码自己编制android so库的过程

    http://blog.csdn.net/lantishua/article/details/21182965 工作需要,在Android上使用OpenCV.opencv当前的版本(2.4.8)已经有 ...

  9. MyBatis学习(二):与Spring整合(非注解方式配置MyBatis)

    搭建SpringMVC的-->传送门<-- 一.环境搭建: 目录结构: 引用的JAR包: 如果是Maven搭建的话,pom.xml的配置如下: <?xml version=" ...

  10. SecureCRT 7.0 如何自动记录日志

    设置步骤如下: 1.打开SecureCRT ,在菜单里选择“选项”-->“全局选项”    2.然后选择“常规”--> “默认会话”--> “编辑默认设置”    3.然后选择“日志 ...