poj 1426 Find The Multiple 题解
题目:给定一个正整数n,编写一个程序来找出n的非零倍数m,其十进制表示形式仅包含数字0和1。您可以假设n不大于200,并且有一个对应的m包含不超过100个十进制数字。
就是找n的只含有0和1的倍数。
(如果这题不放在搜索单元里面你能想到用搜索去做吗?)不过其实只要提示一句搜索自然就能想到这个枚举过程其实就是一个画二叉树的过程,那么自然而然便想到了我们的dfs,这题用dfs可以秒,但是其实我觉得题目是有点问题的,100位的m用long long就可以过了(long long大约是19位),这......就让人很无语,不过减轻了难度咱也没啥好说的,还有就是你用程序跑出来的数值和样例都不一样也可以过,比如6,大家可以试试,我也不知道是哪个对= =,也过了(而且我看了许多博客时其实都一样的),作为一道dfs的练习题,也不要太纠结于此题了,当做一个搜索算法思路的扩展吧
AC代码(DFS)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; long long m; int n; int flag; void dfs(long long ans,int f) { if(flag || f==20) return; //因为long long最多存储19位,而dfs函数中的这个参数每次都是由下一层的函数去判定的,也就是说对于f=20的时候ans达到了19位,这是f为什么取20的原因 if(ans%n==0) { printf("%I64u\n",ans); flag=1; //为什么不能直接在这个地方return结束函数? } else{ dfs(ans*10,f+1); dfs(ans*10+1,f+1); } } int main() { while(scanf("%d",&n) && n!=0) { flag=0; m=0; dfs(1,1); } }
DFS的思路非常清晰就是一个只含有01的二叉树,层次对应位,去寻找符合条件的那个。
重点说明两个地方:
1、f取20是由c++中 long long 的位数决定的,具体也在代码注释中做了解释
2、为什么要设置flag,因为dfs的功能我们之前说过,是一条枝子一条枝子画树的过程,你在某枝的某点上return了,那你其实也只是不往这个枝子下面画了而已,所以为了一旦找到,后面的枝子就都不画了我们设置一个flag便于判断。
关于此题的BFS做法(会T= =)所以不是很推荐,而且这种找到就可以了不用管距离权值啥的,我不是很理解别人的博客上为什么一定要写一个会T的bfs写法。
day4(诶?怎么还是只做了一道水题!)