【第22期】观点:IT 行业加班,到底有没有价值?

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

原创 2015年07月10日 15:48:37

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 (欧拉通路)

D. Tanya and Password time limit per test 2 seconds memory limit per test 256 megabytes ...

[DP]Codeforces Round #264 (Div. 2) D

大致题意: 求多个数列(n=1000)的最长公共子串。   大致思路: 一开始没有头绪,后来发现一点,长度为n的数列中每个数都属于1--n且不重复,所以根据每个数列中每个数字的位置来判定即可。   #include&lt;iostream&gt; #...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

Codeforces Round #288 (Div. 2)---D. Tanya and Password

D. Tanya and Password time limit per test 2 seconds memory limit per test 256 megabytes i...

Codeforces Round #103 (Div. 2) D

div2的D题~~要求距离图上一个点的所有距离为 l 的位置,简单题~~我的方法是先用spfa求出每个点到源点 s 的距离,这样的话每一条边上的点到 s 的最小距离也能推导出来~~然后枚举,枚举每一个点和每一条边 ,枚举边的时候要特别小心,很容易漏掉或者重复计算,这种题目细节是关键。。。 #in...

Codeforces Round #104 (Div. 2) D

简单贪心,数字小的放前面 #include&lt;iostream&gt; #include&lt;vector&gt; #include&lt;algorithm&gt; #include&lt;cstdio&gt; #inclu...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)