Tanya and Password CodeForces - 508D Hash + 欧拉路径

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.
Examples
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

题意就是给定 n 个连续截取产生的字符串,问能不能找到一个可能的母串;
思路:
我们可以这样考虑:对于子串 s ,将 s[ 0 ],s[ 1 ]和 s[ 1 ],s[ 2 ]看成两个点,然后连边,最后我们要找的就是欧拉路;达到该目的,我们只需要 Hash 即可;然后addedge 后,看 indegree & outdegree 是否符合欧拉路的条件,如果满足就跑一下 欧拉路即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 300005
#define inf 0x3f3f3f3f
#define INF 999999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const int mod = 10000007;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-7
typedef pair<int, int> pii;
#define pi acos(-1.0)
#define REP(i,n) for(int i=0;i<(n);i++)

inline int rd() {
	int x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

int n, N;
char s[4];

struct node {
	int to, nxt;
}edge[maxn];
int head[maxn]; int cnt;
void addedge(int u, int v) {
	edge[++cnt].to = v; edge[cnt].nxt = head[u]; head[u] = cnt;
}

int Hhsh(char c) {
	if ('a' <= c && c <= 'z')return c - 'a' + 1;
	else if ('A' <= c && c <= 'Z')return c - 'A' + 27;
	else return c - '0' + 1 + 26 + 26;
}

int Hhsh(char c1, char c2) {
	return Hhsh(c1) * 103 + Hhsh(c2);
}// Hash 

int Hash[maxn];
void init() {
	for (int i = 'a'; i <= 'z'; i++)Hash[i - 'a' + 1] = i;
	for (int i = 'A'; i <= 'Z'; i++)Hash[i - 'A' + 27] = i;
	for (int i = '0'; i <= '9'; i++)Hash[i - '0' + 1 + 26 + 26] = i;
}
int sk[maxn], anscnt = 0, ans[maxn], tot = 0;

void dfs(int x) {
	for (int i = head[x]; i; i = edge[i].nxt) {
		int v = edge[i].to; head[x] = edge[i].nxt;// 删边
		sk[++tot] = v; dfs(v); return;
	}
}

void work(int st) {
	sk[++tot] = st;
	while (tot) {
		int x = sk[tot];
		if (head[x])dfs(x);
		else {
			ans[++anscnt] = x; tot--;
		}
	}
	if (anscnt != n + 1) {
		cout << "NO" << endl; return;
	}
	else {
		cout << "YES" << endl;
		for (int i = anscnt; i >= 1; i--)cout << (char)Hash[ans[i]/103];
		cout << (char)Hash[ans[1]%103] << endl;
	}
}

int indeg[maxn], outdeg[maxn];
int st, ed;
int main()
{
	//ios::sync_with_stdio(false);
	init(); rdint(n);
	
	for (int i = 1; i <= n; i++) {
		scanf("%s", s);
		addedge(Hhsh(s[0], s[1]), Hhsh(s[1], s[2]));
		outdeg[Hhsh(s[0], s[1])]++; indeg[Hhsh(s[1], s[2])]++;
		st = Hhsh(s[0], s[1]);
	}
	ed = Hhsh('9', '9');
	int cnt1 = 0, cnt2 = 0, cnt3 = 0;
	for (int i = 1; i <= ed; i++) {
		int dlt = indeg[i] - outdeg[i];
		if (dlt == 1)cnt1++;
		else if (dlt == 0)cnt2++;
		else if (dlt == -1)cnt3++, st = i;
		else {
			cout << "NO" << endl; return 0;
		}
	}
	if (cnt1 == cnt3 && cnt3 == 0 || cnt1 == cnt3 && cnt3 == 1) {
		work(st); return 0;
	}
	cout << "NO" << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/83054211
今日推荐