• Codeforces 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


    这个题类似poj1780 也是欧拉路的题目 于是类似那个写了一个 发现t了

    原因就是有一组数据

    200000

    zzz

    zzz

    zzz

    ...

    zzz


    这样是一个点 200000个边

    而第i层的dfs 都访问了200000-i次边

    因为第一层 从第一条开始 发现没有被标记过 顺着第一条走到第一个点 开始第二层

    一直到第200000层 都是这样

    然后 200000层发现没有没标记过的边了 返回第199999层之后 199999层会继续遍历已经标记过的后面的边

    一直到第一层 还会便利已经被标记过的第二条到第200000条边 所以会超时

    #include<bits/stdc++.h>
    using namespace std;
    struct self
    {
        int x,y,nxt;
    }s[1000001];
    int fst[1000001];
    
    int h(char* str)
    {
        int ret = str[0]*1000+str[1];
        return ret;
    }
    int g[999999];
    int tot;
    int outd[1000001],ind[1000001];
    int m,n,x,y;
    char str[4],l[4],r[4];
    int ret[1000001],ans;
    char old[1000001][4];
    int pos,num;
    int flag[1000001];
    int ceng;
    void dfs(int u)
    {
        //for(int i=fst[u];i!=-1;i=s[i].nxt)
        for(int i=fst[u];i!=-1;i=fst[u])
        {
            if(!flag[i])
            {
                flag[i]=1;
                //
                fst[u]=s[i].nxt;
                dfs(s[i].y);
                ret[++ans]=i;
            }
        }
    }
    void print()
    {
        if(ans<m)
            printf("NO
    ");
        else
        {
            printf("YES
    ");
            printf("%c",old[s[ret[ans]].x][0]);
            printf("%c",old[s[ret[ans]].x][1]);
            for(int i=ans;i>=1;i--)
                printf("%c",old[s[ret[i]].y][1]);
        }
    }
    
    int main()
    {
        memset(fst,-1,sizeof(fst));
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",str);
            l[0]=str[0];l[1]=str[1];
            r[0]=str[1];r[1]=str[2];
            if(!g[h(l)])
            {
                g[h(l)]=++tot;
                old[tot][0]=l[0];
                old[tot][1]=l[1];
            }
            if(!g[h(r)])
            {
                g[h(r)]=++tot;
                old[tot][0]=r[0];
                old[tot][1]=r[1];
            }
            outd[g[h(l)]]++;
            ind[g[h(r)]]++;
            n++;
            s[n].x=g[h(l)];
            s[n].y=g[h(r)];
            s[n].nxt=fst[g[h(l)]];
            fst[g[h(l)]]=n;
        }
        pos=1;
        int ok=1;
        for(int i=1;i<=tot;i++)
        {
            if(outd[i]!=ind[i])
                num++;
            if(outd[i]==ind[i]+1)
                pos=i;
            if(outd[i]>ind[i]+1 || outd[i]<ind[i]-1)
                ok=0;
        }
        if(!ok)
        {
            printf("NO
    ");
            return 0;
        }
        if(num!=0 && num!=2)
        {
            printf("NO
    ");
            return 0;
        }
        dfs(pos);
        print();
    }


    原来遍历边都是采用这样的方法 就是邻接表的遍历方法

    恩看来要灵活运用啊!

     for(int i=fst[u];i!=-1;i=s[i].nxt)
            if(!flag[i])
            {
                flag[i]=1;
                dfs(s[i].y);
                ans++;
                ret[ans]=i;
            }



  • 相关阅读:
    将Moba的输出导出为文件
    MyBatis入参为0时失效问题
    (笔记)交大电院MEM提前面试优秀经验分享【附面试流程及规则】
    (笔记)GPIO基本原理与寄存器配置(STM32篇)
    (笔记)高速电路板完美走线的诀窍
    使用 python 收集 kubernetes events 并写入 elasticsearch
    java使用io.kubernetes.client-java调用k8s api创建pod/service/ingress示例
    中英文逗号空格分隔符正则式
    SpringCloud学习一-搭建netflix-eureka微服务集群
    Spring 中经典的 9 种设计模式,打死也要记住啊!
  • 原文地址:https://www.cnblogs.com/abgnwl/p/6550344.html
Copyright © 2020-2023  润新知