zoukankan      html  css  js  c++  java
  • POJ1780-Code(欧拉路径求解)

    题目链接:poj1780-Code

    题意:有个保险箱子是n位数字编码,当正确输入最后一位编码后就会打开(即输入任意多的数字只有最后n位数字有效)……要选择一个好的数字序列,最多只需按键10n+n-1次就可以打开保险箱子,即要找到一个数字序列包含所有的n位数一次且仅一次。序列要为字典序。

    题解:首先明白为什么是最多只需按键10n+n-1次。n位数有10n 种编码方案,要一个数字序列包含10n 组n位数且序列最短,只可能是每组数出现一次且仅一次,且前一组数的后n-1位与后一组数的前n-1位相同,10n组数各取一位,再加上最后一组数的n-1位,总共10n +n-1位,如下所示:

    第一组:d1 d2 d3…dn

    第二组:     d2 d3 d4…d(n+1)

    第10n组:…d(10n+n-3) d(10n+n-2) d(10n+n-1)

    然后,把n-1位看成一个图中顶点,将n-1位后加一个数字(0~9)的序列看成一条边,共10n-1个顶点,10n条边,且每条边都不相同,所以这10n组不同的n位数对应图中的一个 欧拉通路。(怎么想过来的呢,你仔细看题目都提示了:题中说,保险箱始终处于10n-1种内部状态之一,假如正确编码为4567,”开锁状态“就是456,如果再输入7就开锁了,如果输入8就切换到新的状态568,然后就想转化到图上来了,把内部状态(n-1位的序列)看成顶点咯。要求解的序列最短,就是从一个顶点出发不重复地遍历所有边到达终点,这不就是赤裸裸的欧拉回路么0.0+)

    注意,该题直接用递归的方法会导致栈溢出,所以要显式地用栈来实现。存储结果时优先存较大值,这样对结果栈逆序输出时就是按字典序排列啦。

    代码实现:

    #include<cstdio>
    const int N=1e5;
    int node[N],stack[10*N];
    char ans[10*N];//结果栈
    int s,a;
    int m;
    void Search(int v){//将当前顶点延伸
        int w;
        while(node[v]<10){//可以在v(n-1位的序列)后加0~9构成10条边
            w=10*v+node[v];
            node[v]++;
            stack[s++]=w;
            v=w%m;
        }
    }
    int main(){
        int n,i,w;
        while(scanf("%d",&n)&&n!=0){
            if(n==1){
                printf("0123456789
    ");
                continue;
            }
            s=a=w=0;
            m=1;
            for(i=0;i<n-1;++i) m*=10;
            for(i=0;i<m;++i) node[i]=0;
            Search(0);
            while(s){
                w=stack[--s];
                ans[a++]=w%10+'0';
                Search(w/10);
            }
            for(i=1;i<n;++i) printf("0");
            while(a) printf("%c",ans[--a]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Redis 主从复制
    Redis 持久化
    Redis 的消息订阅/发布
    Redis 排序功能 -- SORT
    Redis 过期时间与缓存应用
    Redis 事务
    Redis 5种数据类型的常用命令
    Java 框架的核心 -- 反射
    类的加载和初始化 ---- new 一个对象时,在JVM 中的过程是什么
    了解spring
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/5759348.html
Copyright © 2011-2022 走看看