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[*N];
char ans[*N];//结果栈
int s,a;
int m;
void Search(int v){//将当前顶点延伸
int w;
while(node[v]<){//可以在v(n-1位的序列)后加0~9构成10条边
w=*v+node[v];
node[v]++;
stack[s++]=w;
v=w%m;
}
}
int main(){
int n,i,w;
while(scanf("%d",&n)&&n!=){
if(n==){
printf("0123456789\n");
continue;
}
s=a=w=;
m=;
for(i=;i<n-;++i) m*=;
for(i=;i<m;++i) node[i]=;
Search();
while(s){
w=stack[--s];
ans[a++]=w%+'';
Search(w/);
}
for(i=;i<n;++i) printf("");
while(a) printf("%c",ans[--a]);
printf("\n");
}
return ;
}
POJ1780-Code(欧拉路径求解)的更多相关文章
- POJ1780 Code(欧拉路径)
n位密码,要用尽可能短的序列将n位密码的10n种状态的子串都包括,那么要尽量地重合. 题目已经说最短的是10n + n - 1,即每一个状态的后n-1位都和序列中后一个状态的前n-1位重合. 这题是经 ...
- POJ1780 Code
KEY公司开发出一种新的保险箱.要打开保险箱,不需要钥匙,但需要输入一个正确的.由n位数字组成的编码.这种保险箱有几种类型,从给小孩子玩的玩具(2位数字编码)到军用型的保险箱(6位数字编码).当正确地 ...
- NPC问题及其解决方法(回溯法、动态规划、贪心法、深度优先遍历)
NP问题(Non-deterministic Polynomial ):多项式复杂程度的非确定性问题,这些问题无法根据公式直接地计算出来.比如,找大质数的问题(有没有一个公式,你一套公式,就可以一步步 ...
- 再谈循环&迭代&回溯&递归&递推这些基本概念
循环:不断重复进行某一运算.操作. 迭代:不断对前一旧值运算得到新值直到达到精度.一般用于得到近似目标值,反复循环同一运算式(函数),并且总是把前一 次运算结果反代会运算式进行下一次运算 递推:从初值 ...
- low-rank 的相关求解方法 (CODE) Low-Rank Matrix Recovery and Completion via Convex Optimization
(CODE) Low-Rank Matrix Recovery and Completion via Convex Optimization 这个是来自http://blog.sina.com.cn/ ...
- ACM/ICPC 之 暴力打表(求解欧拉回路)-编码(POJ1780)
///找到一个数字序列包含所有n位数(连续)一次且仅一次 ///暴力打表 ///Time:141Ms Memory:2260K #include<iostream> #include< ...
- C++ code:数值计算之辛普生(Simpson)法求解积分问题
- C++ code:数值计算之矩形法求解积分问题
积分的通常方法是将区域切割成一个个的小矩形,然后求这些小矩形的和.小矩形切割得越细,计算精度就越高,可以将切割小矩形的数量作为循环迭代变量,将前后两个不同精度下的小矩形和之差,作为逼近是否达到要求的比 ...
- RNN求解过程推导与实现
RNN求解过程推导与实现 RNN LSTM BPTT matlab code opencv code BPTT,Back Propagation Through Time. 首先来看看怎么处理RNN. ...
随机推荐
- CG基础教程-陈惟老师十二讲笔记
转自 麽洋TinyOcean:http://www.douban.com/people/Tinyocean/notes?start=50&type=note 因为看了陈惟十二讲视频没有课件,边 ...
- 6.mybatis异常:SQL Mapper Configuration,Error parsing Mapper XML,Could not resolve type alias
在xxxMapper中 <select id="getClazz" parameterType="int" resultType="getCla ...
- So easy Webservice 8.spring整合CXF 发布WS
1.添加jar包(cxf的jar包中包含了spring的jar包),添加spring配置文件 2.web.xml中配置CXFServlet,过滤WS服务的地址 <!-- 配置CXFServlet ...
- iOS - OC 内存管理
1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对 ...
- SAP供应商和客户的创建
进来遇到一个创建供应商的需求,由于在系统中关于供应商和客户的创建比较特殊,且没有相关函数进行创建, 找到一个类和方法来创建,类名:VMD_EI_API 方法名:MAINTAIN_DIRECT_INP ...
- eclipse 安装git
1.安装Git 首先安装Git.这里只讲Windows环境下安装Git方法. 从Git下载git的Windows安装文件,一路Next到选择安装组件这一步: 选上Git Bash Here这一项,这样 ...
- Linux_文档编辑器_简介
1. vi 2. vim 3. ubuntu 有一个 自己的图形化的 文档编辑器,用起来比较方便: gedit 4. 5.
- hdu3007Buried memory(最小圆覆盖)
链接 普通的暴力复杂度达到O(n^4),对于这题肯定是不行的. 解法:随机增量算法 参考http://www.2cto.com/kf/201208/149602.html algorithm:A.令C ...
- php三维数组变二维数组
<?php $result = Array(0 => Array(0 => Array(bid => 41,brealname => 'we教官',cid => 4 ...
- POJ 3468(树状数组的威力)
之前说过这是线段树的裸题,但是当看了http://kenby.iteye.com/blog/962159 这篇题解后我简直震惊了,竟然能如此巧妙地转化为用树状数组来处理,附上部分截图(最好还是进入原网 ...