CF 508D(Tanya and Password-欧拉路径,弗罗莱算法)

D. Tanya and Password

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

While dad was at work, a little girl Tanya decided to play with dad‘s password to his secret database. Dad‘s password is a string consisting of n?+?2 characters.
She has written all the possible n three-letter continuous substrings of the password on pieces of paper, one for each piece of paper, and threw the password
out. Each three-letter substring was written the number of times it occurred in the password. Thus, Tanya ended up with n pieces of paper.

Then Tanya realized that dad will be upset to learn about her game and decided to restore the password or at least any string corresponding to the final set of three-letter strings. You have to help her in this difficult task. We know that dad‘s password consisted
of lowercase and uppercase letters of the Latin alphabet and digits. Uppercase and lowercase letters of the Latin alphabet are considered distinct.

Input

The first line contains integer n (1?≤?n?≤?2·105),
the number of three-letter substrings Tanya got.

Next n lines contain three letters each, forming the substring of dad‘s password. Each character in the input is a lowercase or uppercase Latin letter or
a digit.

Output

If Tanya made a mistake somewhere during the game and the strings that correspond to the given set of substrings don‘t exist, print "NO".

If it is possible to restore the string that corresponds to given set of substrings, print "YES", and then print any suitable password option.

Sample test(s)

input

5
aca
aba
aba
cab
bac

output

YES
abacaba

input

4
abc
bCb
cb1
b13

output

NO

input

7
aaa
aaa
aaa
aaa
aaa
aaa
aaa

output

YES
aaaaaaaaa

欧拉路径,弗罗莱算法 主要参见下面的资料:

http://blog.csdn.net/u012659423/article/details/43319245

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXLen (200000+10)
#define MAXN (200000+10)
#define MAXM (MAXLen)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n,N;
char s[4];
int pre[MAXN]={0},next[MAXM]={0},edge[MAXM],size=0;
void addedge(int u,int v)
{
	edge[++size]=v;
	next[size]=pre[u];
	pre[u]=size;
}
int indegree[MAXN],outdegree[MAXN];
int h(char c)
{
	if ('a'<=c&&c<='z') return c-'a'+1;
	if ('A'<=c&&c<='Z') return c-'A'+27;
	else return c-'0'+1+26+26;
}
int h(char c1,char c2)
{
	return h(c1)*63+h(c2);
}
int ans[MAXLen],anstot=0,S[MAXN],tot=0;
int hash[MAXLen];
void dfs(int x)
{
	Forp(x)
	{
		int v=edge[p];
		pre[x]=next[p];
		S[++tot]=v;
		dfs(v);
		return ;
	}
}
void Fleury(int st)
{
	S[++tot]=st;
	while (tot)
	{
		int x=S[tot];
		if (pre[x]) dfs(x);
		else
		{
			ans[++anstot]=x;
			tot--;
		}
	}

	if (anstot^(n+1))
	{
		cout<<"NO\n";
		return;
	}
	cout<<"YES\n";
	ForD(i,anstot)
	{
		printf("%c",hash[ans[i]/63]);
	}
	printf("%c\n",hash[ans[1]%63]);

}
int main()
{
//	freopen("CF508D.in","r",stdin);
//	freopen(".out","w",stdout);

	Fork(i,'a','z') hash[i-'a'+1]=i;
	Fork(i,'A','Z') hash[i-'A'+27]=i;
	Fork(i,'0','9') hash[i-'0'+1+26+26]=i;

	cin>>n;
	int st=0;
	For(i,n)
	{
		scanf("%s",s);
		addedge(h(s[0],s[1]),h(s[1],s[2]));
		outdegree[h(s[0],s[1])]++,indegree[h(s[1],s[2])]++;
		st=h(s[0],s[1]);
	}
	N=h('9','9');
	int s1=0,s2=0,s3=0;
	For(i,N)
	{
		int t=indegree[i]-outdegree[i];
		if (t==1) ++s1;
		else if (t==0) ++s2;
		else if (t==-1) ++s3,st=i;
		else
		{
			cout<<"NO\n";
			return 0;
		}
	} 

	if ((s1==s3&&s3==0)||(s1==s3&&s3==1))
	{
		Fleury(st);
		return 0;
	}

	cout<<"NO\n";
	return 0;

	return 0;
}
时间: 2024-12-23 02:19:40

CF 508D(Tanya and Password-欧拉路径,弗罗莱算法)的相关文章

Fleury (弗罗莱) 算法通俗解释

Fleury (弗罗莱) 算法通俗解释 1.定义 2.举例说明 图2为连通图G,现利用Fleury算法求它的欧拉通路.(注意区分:欧拉通路.欧拉回路) 其中一种欧拉通路如下:4 5 8 7 6 8 9 1 5 3 2 4 6,其搜索路径如下图所示: 现在让我们来分析算法实现过程: 假设我们这样走:4,6,8,5,此时在5处有三种选择(3,4,1),那么哪种能走通哪种走不通呢?答案是(3,4)通,1不通.为什么呢?来看下图- 分析: 因为(5~1)之间的边是除去已走过边(E(G)-{E1(4~6)

CodeForces - 508D Tanya and Password(欧拉通路)

Description While dad was at work, a little girl Tanya decided to play with dad's password to his secret database. Dad's password is a string consisting of n + 2 characters. She has written all the possible n three-letter continuous substrings of the

Codeforces 508D Tanya and Password

题意: n(10^5)个串每个串3个字符  两个串abc.xyz能拼在一起前提是b=x&&c=y  它们能拼成ab(x)c(y)z  求n个串品在一起的串 思路: 将串abc变成ab->bc的一条边  则原题变成了有向图的欧拉路径问题 有向图欧拉路径算法就是遍历  因为欧拉路径其实就是"每条边走一遍" 代码: #include<cstdio> #include<iostream> #include<cstring> #inclu

codeforces 508D . Tanya and Password 欧拉通路

题目链接 给你n个长度为3的子串, 这些子串是由一个长度为n+2的串分割得来的, 求原串, 如果给出的不合法, 输出-1. 一个欧拉通路的题, 将子串的前两个字符和后两个字符看成一个点, 比如acb, 就是ac->cb. 然后建图. 1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm>

Codeforces 508D Tanya and Password 欧拉通路Euler

题目链接:点击打开链接 题意:给定n个长度为3各不相同的字符串,猜一个n+2位的密码. 这个密码包含上面的所有字符串 思路: 把 abc 拆成ab -> bc 则得到一个图,目标就是走遍所有 ab->bc 这样的边,也就是找一条欧拉通路. #include <cstdio> #include <algorithm> #include <string.h> #include <queue> #include <cstring> #inc

Fleury(弗罗莱)算法求欧拉回路

转自http://www.cnblogs.com/Lyush/archive/2013/04/22/3036659.html 上面是摘自图论书上的定义. 算法在运行过程中删除了所有已走的路径,也就是说途中残留了所有没有行走的边.根据割边的定义,如果在搜索过程中遇到割边意味着当前的搜索路径需要改进,即提前输出某一个联通子集的访问序列,这样就能够保证访问完其中联通子图中后再通过割边访问后一个联通子图,最后再沿原路输出一开始到达该点的路径.如果只有割边可以扩展的话,只需要考虑先输出割边的另一部分联通子

codeforces 508 D. Tanya and Password (fleury算法)

codeforces 508 D. Tanya and Password (fleury算法) 题目链接: http://codeforces.ru/problemset/problem/508/D 题意: 给出n个长度为3的字符串,如:abc bca aab 如果一个字符串的长度为2的后缀等于,另外一个字符串的长度为2的前缀,则这两个字符串能连起来,比如:aabca,然后这n个字符串可以形成一个图,求图上的一条欧拉通路. 限制: 1 <= n <= 2*10^5,字符串里面有大写字母,小写字

腾讯webqq最新password加密算法,hash算法

常常在做webqq机器人,可是最头痛的问题就是腾讯常常加一些验证串来防止robot,如今共享出最新的腾讯password加密算法和hash 算法 hash算法 def webqq_hash(i, a): if isinstance(i, (str, unicode)): i = int(i) class b: def __init__(self, _b, i): self.s = _b or 0 self.e = i or 0 r = [i >> 24 & 255, i >>

Codeforces 526D Tanya and Password kmp

题意:给你一个字符串 ,问你前对于任意一个前缀能不能组成  A+B+A+B...+B+A 这种形式. 解题思路:在next数组上面乱搞,判断前缀是否循环 ,循环是否为K还是K+1,为K的时候往后DP看最多能符合条件的前缀串. 解题代码: 1 // File Name: d.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月06日 星期一 15时36分38秒 4 5 #include<vector> 6 #include<list&