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>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef unsigned long long ULL;
#define N 3850

int n,m;
int in[N],out[N],Edge[N][N],ans[200010];

int get(char a){
    if(a>='0'&&a<='9') return a-'0';
    if(a>='A'&&a<='Z') return a-'A'+10;
    return a-'a'+36;
}
char put(int a){
    if(a>=0&&a<=9) return '0'+a;
    if(a>=10&&a<=35) return 'A'+a-10;
    return 'a'+a-36;
}

void dfs(int x){
    for(int i=0;i<N;i++){
        while(Edge[x][i]){
            Edge[x][i]--;
            dfs(i);
            ans[m++]=i;
        }
    }
}

int main(){
    char s[10];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        int u=get(s[0])*62+get(s[1]);
        int v=get(s[1])*62+get(s[2]);
        in[v]++;
        out[u]++;
        Edge[u][v]++;
    }
    int can=1,st=-1,ed=-1;
    for(int i=0;i<N;i++){
        int tmp=in[i]-out[i];
        if(abs(tmp)>1){
            can=0;
            break;
        }else if(tmp==1){
            if(ed==-1) ed=i;
            else{
                can=0;
                break;
            }
        }else if(tmp==-1){
            if(st==-1) st=i;
            else{
                can=0;
                break;
            }
        }
    }
    if(can){
        if(st==-1){
            for(int i=0;i<N;i++) if(out[i]){
                st=i;
                break;
            }
        }
        dfs(st);
        ans[m++]=st;
        if(m==n+1){
            puts("YES");
            for(int i=m-1;i>=0;i--){
                if(i!=m-1) printf("%c",put(ans[i]%62));
                else printf("%c%c",put(ans[i]/62),put(ans[i]%62));
            }
            puts("");
        }else puts("NO");
    }
    else puts("NO");
    return 0;
}
时间: 2024-10-05 03:31:14

Codeforces 508D Tanya and Password的相关文章

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个长度为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

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&

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,字符串里面有大写字母,小写字

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

[2016-03-31][codeforces][659C][Tanya and Toys]

时间:2016-03-31 23:49:13 星期四 题目编号:[2016-03-31][codeforces][659C][Tanya and Toys].md 题目大意:有$10^9$种物品,第i种物品价值i,已经用用n个物品,给m元,问最多能买多少个还没拥有的物品 分析:贪心,从最低的开始买起,假设$m = 10^9$,那么也买的物品也不超过$10^6$个,因为$\frac{(1+k)k}{k} < 10^9$ 遇到的问题:答案可能为0 #include <algorithm> #

codeforces 659C Tanya and Toys

题目链接:http://codeforces.com/problemset/problem/659/C 题意: n是已经有的数字,m是可用的最大数字和 要求选自己没有的数字,且这些数字的数字和不能超过m 且要求可选的数字的数目越多越好 输出一种答案即可 解题思路: 刚开始想开一个bool型的1e9的数组,然后判断即可 可是交上去发现内存超限 后来把1e9的数组改成2*1e6的数组即可 具体原因应该从数学数字和方面考虑 具体代码如下: #include<bits/stdc++.h> using

Codeforces 761C Dasha and Password(枚举+贪心)

题目链接 Dasha and Password 题目保证一定有解. 考虑到最多只有两行的指针需要移动,那么直接预处理出该行移动到字母数字或特殊符号的最小花费. 然后O(N^3)枚举求最小值即可. 时间复杂度O(N*M+N^3) 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define rep(i,a,b) for(int i(