• 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;
            }



  • 相关阅读:
    ul制作导航菜单
    HTML5+CSS (简易nav设计)
    鼠标事件-拖拽(滑块控制物体透明度变化)
    鼠标事件-拖拽5(带虚线框的拖拽)
    鼠标事件-拖拽4(捕获)
    鼠标事件-拖拽3(磁性吸附)
    鼠标事件-拖拽2(不能拖出指定对象的div)
    生成整数排列的方法
    python工具程序一、复制目录中指定扩展名的文件
    Anaconda packages list
  • 原文地址:https://www.cnblogs.com/abgnwl/p/6550344.html
Copyright © 2020-2023  润新知