Codeforces Round #288 (Div. 2) D. Tanya and Password 欧拉回路

2024-05-14 11:58

本文主要是介绍Codeforces Round #288 (Div. 2) D. Tanya and Password 欧拉回路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

D. Tanya and Password
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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
题意,给出一个字符串的每三位所得到的n-2个字符串(顺序打乱)要求原来的那个字符串!
以每个字符串的前两个 后两个看成点,连条线,建成图,原问题就转化成了要求过每条边一次的路径,也就是欧拉通路,判定欧拉通路要求全部是偶度点或者只有两个奇度点,且这两个点,一个出度比入度大一,就是起点,一个出度比入度小一,就是终点,使用Fleury算法,注意,图不一定连通,且如果自已连自已的边可以使用数组记录下来,优化一下!因为每条边只经过一次,复杂度O(m),m是边数!

#define INF         9000000000
#define EPS         (double)1e-9
#define mod         1000000007
#define PI          3.14159265358979
//*******************************************************************************/
#endif
#define N 200050
#define M 4005
#define maxn 205
#define MOD 1000000000000000007
struct edge{int s,e,in;edge(){}edge(int ss,int ee,int inn){s = ss;e = ee;in = inn;}
};
int n,ansi,dp[M],in[N],out[N];
bool vis[N];
char str[N][4],ans[N];
vector<edge> p[M];
int charNum(char a){if(a>='a' && a<='z') return a-'a';if(a>='A' && a<='Z') return a-'A' + 26;if(a>='0' && a<='9') return a-'0' + 52;return 0;
}
char enchar(int a){if(a<26){return a+'a';}else if(a<52){return a-26+'A';}else {return a-52 + '0';}
}
int SumNum(char a,char b){return charNum(a) * 62 + charNum(b);
}
void DFS(int pos){printf("%d \n",pos);FJ(p[pos].size()){if(!vis[p[pos][j].in] ){vis[p[pos][j].in] = true;DFS(p[pos][j].e);p[pos].erase(p[pos].begin() + j);j--;}}if(dp[pos]>0){FI(dp[pos]){ans[ansi++] = enchar(pos%62);}dp[pos] = 0;}ans[ansi++] = enchar(pos%62);
}
int main()
{while(S(n)!=EOF){memset(vis,false,sizeof(vis));memset(in,0,sizeof(in));memset(out,0,sizeof(out));memset(dp,0,sizeof(dp));FI(M) p[i].clear();FI(n){SS(str[i]);int s1 = SumNum(str[i][0],str[i][1]);int s2 = SumNum(str[i][1],str[i][2]);if(s1 != s2){p[s1].push_back(edge(s1,s2,i));out[s1]++,in[s2]++;}else {dp[s1]++;}}int flag = 0,start = -1,end = -1;FI(M){if(in[i] != out[i]){flag ++;if(end == -1 && in[i] == out[i] + 1){end = i;}else if(start == -1 && in[i]+1 == out[i]){start = i;}else {flag = 3;}}}if(flag == 0 || flag == 2){if(start == -1) start = SumNum(str[0][0],str[0][1]);ansi = 0;DFS(start);ans[ansi++] = enchar(start/62);if(ansi != n+2) {printf("NO\n");continue;}printf("YES\n");for(int i=ansi-1;i>=0;i--) printf("%c",ans[i]);printf("\n");}else {puts("NO");}}return 0;
}

这篇关于Codeforces Round #288 (Div. 2) D. Tanya and Password 欧拉回路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/988690

相关文章

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

欧拉系统 kernel 升级、降级

系统版本  cat  /etc/os-release  NAME="openEuler"VERSION="22.03 (LTS-SP1)"ID="openEuler"VERSION_ID="22.03"PRETTY_NAME="openEuler 22.03 (LTS-SP1)"ANSI_COLOR="0;31" 系统初始 kernel 版本 5.10.0-136.12.0.

nyoj 288 士兵杀敌(五)

一道插线问线离线版的题  复杂度O(n); 代码如下: #include<stdio.h>#include<string.h>const int M = 1000003;const int mod=10003;int num[M];int main(){int n,c,q;scanf("%d%d%d",&n,&c,&q);while(c--){int a,b,x;scan