POJ 1780(欧拉路)

本文详细介绍了如何解决POJ1780和HDU2894这类问题,通过创建图并使用Euler路径算法找到解决方案。特别指出,HDU2894的问题可以通过将串视为环来简化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ 1780和HDU 2894基本一样

这两道题做法完全相同,唯一的区别就是HDU 2894是一个环(其实也不算区别。。)

 

方法就是:对于每一个长度为n的串,让该串的前n-1位为一个节点,后n-1位为另一个节点这样就确定了这个串。

PS:POJ 1780递归会爆栈的,只好写手工站,第一次写,一开始写的超麻烦,后来借鉴别人的了。。还是蒟蒻。。

 

View Code
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #define M 1001000
 5 using namespace std;
 6 int to[M],head[M],len[M],next[M],top,cnt,n,dk,ans[M];
 7 bool vis[M];
 8 int fc[8]={1,10,100,1000,10000,100000,1000000};
 9 struct STACK
10 {
11     int x,p;
12 }stack[M];
13 void add(int u,int v,int w)
14 {
15     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
16 }
17 void create()
18 {
19     memset(head,-1,sizeof head);
20     memset(vis,0,sizeof vis);
21     cnt=0;
22     for(int i=0,tmp;i<fc[n-1];i++)
23     {
24         tmp=i%fc[n-2];
25         for(int j=9;j>=0;j--)//字典序最小
26             add(i,tmp*10+j,i*10+j);
27     }
28 }
29 void euler()
30 {
31     int u,pos;
32     top=2; dk=0;
33     stack[1].x=0; stack[1].p=head[0];
34     while(top)
35     {
36         u=stack[top-1].x; pos=stack[top-1].p;
37         for(;~pos;pos=next[pos])
38             if(!vis[pos])
39             {
40                 stack[top-1].p=pos;
41                 vis[pos]=true;
42                 stack[top].p=head[to[pos]]; stack[top].x=to[pos];  ++top;
43                 break;
44             }
45         if(pos==-1)//扫完u了,相当于递归完毕 
46         {
47             ans[++dk]=stack[top-1].p;
48             top--;
49         } 
50     }
51 }
52 void prt()
53 {
54     for(int i=1;i<n;i++) printf("0");
55     for(int i=dk-1;i>=2;i--) printf("%d",len[ans[i]]%10);
56     printf("\n");
57 }
58 void go()
59 {
60     create();
61     euler();
62     prt();
63 }
64 int main()
65 {
66     while(scanf("%d",&n),n)
67     {
68         if(n==1) printf("0123456789\n");
69         else go();
70     }
71     return 0;
72 }
73     

 

 

HDU 2894:http://www.cnblogs.com/proverbs/archive/2012/08/21/2649984.html

转载于:https://www.cnblogs.com/proverbs/archive/2012/08/29/2662416.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值