zoukankan      html  css  js  c++  java
  • POJ1780 欧拉路+手写栈解决爆战问题

    题目链接:http://poj.org/problem?id=1780

    本题中给出一个位数n,要求给出一个10^n+n-1位数的数,要求每个n位的数都要在里面出现,一个n位的数一共有10^n种,我们容易想到每一位其实都代表一个数,然后最后一个数与之后的n-1位数都成n位的数。第一位的数与之后的五位数是组成一种密码,之后的数的首部n-1位数都与前面的数尾部n-1位数相连,这种类似“首尾相连”的情况很容易让人想到欧拉回路。但是10^6深度dfs会爆栈,所以考虑手写栈。

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <vector>
     7 #include <set>
     8 #include <queue>
     9 #include <map>
    10 using namespace std;
    11  
    12 #define MP make_pair
    13 #define ll long long
    14 #define inf 0x3f3f3f3f
    15 #define maxn 100010
    16 #define maxm 1000010
    17 int ten[]={1,10,100,1000,10000,100000,1000000};
    18 struct Edge{
    19     int v,nxt;
    20     bool vis;
    21 }e[maxm];
    22 int head[maxn],esz;
    23 void init(){esz=0;memset(head,-1,sizeof(head));}
    24 void addedge(int u,int v){
    25     e[esz].v=v,e[esz].nxt=head[u];
    26     e[esz].vis=false;
    27     head[u]=esz++;
    28 }
    29 int st[maxm],top;
    30 int ans[maxm];
    31 int main(){
    32     //freopen("out","w",stdout);
    33     int n,m;
    34     while(~scanf("%d",&n) && n){
    35         if(n==1){puts("0123456789");continue;}
    36         init();
    37         for(int i=0;i<ten[n-1];++i){
    38             int x = i%ten[n-2];
    39             for(int j=9;j>=0;--j){
    40                 addedge(i,x*10+j);//扩展新的边 
    41             }
    42         }
    43         top=0;
    44         int sz=0;
    45         st[top++]=0;
    46         while(top){
    47             int u = st[--top];
    48             bool f=false;
    49             for(int i=head[u];i!=-1;i=e[i].nxt){
    50                 int v = e[i].v;
    51                 if(e[i].vis) continue;
    52                 e[i].vis = true;
    53                 st[top++]=u;
    54                 st[top++]=v;
    55                 f=true;
    56                 break;
    57             }
    58             if(f==false) ans[sz++]=u;
    59         }
    60         for(int i=0;i<n-2;++i) ans[sz++]=0;
    61         //for(int i=sz-1;i>=0;--i) printf("%d ",ans[i]); puts("");
    62         for(int i=sz-1;i>=0;--i) printf("%d",ans[i]%10);
    63         puts("");
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    Nowcoder9981A.串(排列组合)
    267D.Fedor and Essay(强连通分量缩点+DAG上DP)
    1290C. Prefix Enlightenment(带权并查集)
    LeetCode1. 两数之和
    LeetCode451. 根据字符出现频率排序
    LeetCode205. 同构字符串
    LeetCode290. 单词规律
    LeetCode202. 快乐数
    LeetCode242. 有效的字母异位词
    LeetCode136. 只出现一次的数字
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12579216.html
Copyright © 2011-2022 走看看