• POJ 1780 【手工递归】【欧拉回路】


    题意:

    1.提供密码的位数。

    2.密码的输入可以一直保持,取后n位作为密码。如果密码正确则开锁。

    3.设计一种方法使得在输入最少的情况下破译。(即保证每个密码只输入一次)

    4.输出输入的数字的序列。

    思路:

    去密码的前n-1位作为状态节点,将n位数密码作为边。建造有向图。

    显然,每个点的入度和出度都为10,则一定存在欧拉回路。

    利用简单DFS寻找欧拉回路。

    (这题好像是要求输出字典序最小的序列)

    DFS应该不难写,但是这题如果直接递归会爆栈。所以需要手工用栈模拟递归的过程...

    屌丝看了大神的关于递归定义的博客才对递归有了更深刻的理解...

    博客地址:http://www.tuicool.com/articles/BrIVz2

    ==以前lz只是把递归当作快速插入代码的东西来用==

    代码:

    #include<stdio.h>
    #include<string.h>
    int n,e,tmpe,s;
    bool out[1000000][11];
    int road[1000050];
    int mypos[1000050];
    int pos[1000050];
    void solve()
    {
        int load=1;
        bool needop=1;
        int tmpn=1;
        memset(out,1,sizeof(out));
        memset(mypos,0,sizeof(mypos));
        pos[1]=0;
        s=1;
        e=1;
        tmpe=1;
        for(int i=1; i<=n; i++)
        {
            e*=10;
        }
        tmpe=e/100;
        while(s)
        {
            if(load==1)
            {
                mypos[s]=0;
                load=0;
                continue;
            }
            else if(load==-1)
            {
                out[pos[s]][mypos[s]-1]=1;
                load=0;
                continue;
            }
            else
            {
                if(mypos[s]==10)
                {
                    s--;
                    load=-1;
                    continue;
                }
                else if(!out[pos[s]][mypos[s]])
                {
                    mypos[s]++;
                    load=0;
                    continue;
                }
                else
                {
                    load=1;
                    int tmp=(pos[s]-pos[s]/tmpe*tmpe)*10+mypos[s];
                    road[s]=pos[s]*10+mypos[s];
                    out[pos[s]][mypos[s]]=0;
                    mypos[s]++;
                    s++;
                    pos[s]=tmp;
                }
            }
            if(s>e)
                break;
        }
        for(int i=1;i<n;i++)
            printf("0");
        for(int i=1;i<=e;i++)
        {
            printf("%d",road[i]%10);
        }
        printf("
    ");
    }
    int main()
    {
        scanf("%d",&n);
        while(n)
        {
            if(n==1)
                printf("0123456789
    ");
            else
                solve();
            scanf("%d",&n);
        }
    }

    下面是直接递归的代码:

    #include<stdio.h>
    #include<string.h>
    int n,e,tmpe;
    bool out[1000000][11];
    bool in[1000000][11];
    bool vis[1000000];
    int road[1000050];
    int num;
    bool dfs(int pos,int nn)
    {
        if(nn==e-1)
            return 1;
        for(int i=0;i<10;i++)
        {
            if(out[pos][i])
            {
                out[pos][i]=0;
                int tmp=(pos-pos/tmpe*tmpe)*10+i;
                road[nn]=pos*10+i;
                if(dfs(tmp,nn+1))
                    return 1;
                out[pos][i]=1;
            }
        }
        return 0;
    }
    void solve()
    {
        memset(in,1,sizeof(in));
        memset(out,1,sizeof(out));
        memset(vis,0,sizeof(vis));
        e=1;
        tmpe=1;
        for(int i=1;i<=n;i++)
        {
            e*=10;
        }
        tmpe=e/100;
        dfs(0,0);
        for(int i=0;i<e-1;i++)
        {
            printf("%d
    ",road[i]);
        }
    }
    int main()
    {
        scanf("%d",&n);
        while(n)
        {
            if(n==1)
                printf("0123456789
    ");
            else
                solve();
            scanf("%d",&n);
        }
    }
  • 相关阅读:
    C语言I博客作业02
    C语言I博客作业06
    C语言I—2019秋作业第一周作业
    C语言I博客作业09
    C语言I博客作业07
    C语言I博客作业08
    利用 jrebel 热部署\远程调试\远程热部署 springboot项目 服务器上的代码
    java 双因素认证(2FA)TOTP demo
    java File读取文件始终不存在的问题分析
    exchange 2010 的两个错误
  • 原文地址:https://www.cnblogs.com/tun117/p/4865116.html
Copyright © 2020-2023  润新知