zoukankan      html  css  js  c++  java
  • POJ 1780 Code(欧拉回路+非递归dfs)

    http://poj.org/problem?id=1780

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

    思路:

    对于当前长度为n-1的序列,其后添加一个数字,使得添加后的序列没有在前面出现过。这样的话,以n-1位数为顶点,新增一个数后构成n位数为边,到达后n-1位数的新顶点。这样一来,就构成了一个图,我们只要不重复的经过图中所有边即可,那么这就是欧拉回路了。

    在寻找路径的时候需要用dfs,但是吧,这里直接dfs是要爆栈的,所以这里必须要用非递归的方法来实现dfs,也就是要借助栈。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 1e5 + 5;
    17 
    18 int n;
    19 int s,t,v;
    20 int list[maxn];
    21 int sta[maxn*10];
    22 char ans[maxn*10];
    23 
    24 void search(int v, int m)
    25 {
    26     int w;
    27     while(list[v]<10)
    28     {
    29         int w=v*10+list[v];
    30         list[v]++;
    31         sta[s++]=w;
    32         v=w%m;
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     //freopen("in.txt","r",stdin);
    39     while(~scanf("%d",&n) && n)
    40     {
    41         if(n==1)
    42         {
    43             puts("0123456789");
    44             continue;
    45         }
    46         int m=pow(10.0,(double)(n-1));
    47         for(int i=0;i<m;i++)   list[i]=0;  //list【i】记录了i顶点接下来要走的边,因为是要按字典序顺序,
    48                                            //所以它肯定先走添加0的,然后1,2...直到9
    49 
    50         s=0,t=0,v=0;
    51         search(v,m);  //从起点出发会有10条边可走,先从起点出发随便走一条,当然也不是随便的...先走一下字典序小的那条路
    52         while(s)  //有些顶点可能还有别的路可以走,所以继续选择顶点把该顶点剩余的未走的边走完
    53         {
    54             v=sta[--s]; ans[t++]=v%10+'0';
    55             v/=10;
    56             search(v,m);
    57         }
    58         for(int i=1;i<n;i++)   printf("0");
    59         while(t)  printf("%c",ans[--t]);
    60         printf("
    ");
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    耐人寻味的 8 幅Java技术图
    什么是线程安全?怎么样才能做到线程安全?
    线程池
    ExecutorService的正确关闭方法
    js中let和var定义变量的区别
    sql的left join 、right join 、inner join之间的区别
    Collections.sort排序
    Mysql声明变量及使用
    java集合容器汇总
    TortoiseSVN提交commit提示Unable to create pristine install stream.系统找不到指定的路径 之解决方法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7200799.html
Copyright © 2011-2022 走看看