码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-10-09 21:24:35      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题意:

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("\n");
}
int main()
{
    scanf("%d",&n);
    while(n)
    {
        if(n==1)
            printf("0123456789\n");
        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\n",road[i]);
    }
}
int main()
{
    scanf("%d",&n);
    while(n)
    {
        if(n==1)
            printf("0123456789\n");
        else
            solve();
        scanf("%d",&n);
    }
}

 

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

标签:

原文地址:http://www.cnblogs.com/tun117/p/4865116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!