POJ 1426 Find The Multiple

题意:给定一个整数n,求n的一个倍数,要求这个倍数只含0和1

参考博客:点我

解法一:普通的BFS(用G++能过但C++会超时)

    从小到大搜索直至找到满足条件的数,注意最高位一定为1

    假设 n=6  k即为当前所求的目标数,不满足条件则进一步递推 (i 为层数(深度),在解法二的优化中体现,此时可以不管)


    1%6=1 (k=1)  i=1
    {
      (1*10+0)%6=4 (k=10)  i=2
      {
        (10*10+0)%6=4 (k=100)  i=4
        {
          (100*10+0)%6=4 (k=1000)  i=8
          (100*10+1)%6=5 (k=1001)  i=9
        }
        (10*10+1)%6=5 (k=101)  i=5
        {
          (101*10+0)%6=2 (k=1010)  i=10
          (101*10+1)%6=3 (k=1011)  i=11
        }
      }

      (1*10+1)%6=5 (k=11)  i=3
      {
        (11*10+0)%6=2 (k=110)  i=6
        {
          (110*10+0)%6=2 (k=1100)  i=12
          (110*10+1)%6=3 (k=1101)  i=13
        }
        (11*10+1)%6=3 (k=111)  i=7
        {
          (111*10+0)%6=0 (k=1110)  i=14 有解
          (111*10+1)%6=1 (k=1111) 由于前面有解,这个余数不存储
        }
      }
}

可以看到,如此反复枚举下去,直至找到目的数k为止,注意若当前k不满足条件,则将k*10 和k*10 + 1入队以便进一步判断

以下是解法一的代码,用G++能过,但用C++超时(我是在hust交的),不知道为什么!

  1. /* POJ 1426 Find The Multiple BFS 用C++超时但G++过了*/
  2. #include <cstdio>
  3. #include <queue>
  4. using namespace std;
  5.  
  6. /*返回最大能整除n的只有1和0组成的数*/
  7. long long bfs(int n){
  8. long long tmp;
  9. queue<long long> q;
  10. q.push();
  11. while (!q.empty()){
  12. tmp = q.front();
  13. q.pop();
  14. if (tmp % n == ){
  15. return tmp;
  16. }
  17. q.push(tmp * );
  18. q.push(tmp * + );
  19. }
  20. return ;
  21. }
  22.  
  23. int main()
  24. {
  25. int n;
  26. while (scanf("%d", &n) == && n){
  27. printf("%lld\n", bfs[n]);
  28. }
  29.  
  30. return ;
  31. }

解法二:优化的BFS(C++能过)

由于C++超时,于是我参考了以下别人的代码,地址上面已给出,但为了加深记忆,还是自己写一遍!

同余定理的应用:

        (a+b)%n = (a%n + b%n)%n

        (a*b)%n =  (a%n * b%n)%n

在解法一中,由于一直*10, k有可能出现越界,具体请参考原博客,在这里只写余数优化过程:

取解法一中的任意式子:

  前一层: mod =  (11*10 + 0)%6 = 2, k = 110, i = 6, k % 6 = 2

  后一层: mod = (k'*10 + 0) %6   //注意这里的k'为上一层的k,即110, 另此层k为110*10 + 0, i 为6 * 2

           =( (k'*10)%6 + 0%6 ) % 6

         =( (k'%6 * 10%6) % 6 + 0%6) % 6   //k'%6即为上一层的mod,记为mod', 在这个例子中就是2, 另k'%6 = mod' = mod'%6

           =( (mod'6 * 10%6) % 6 + 0%6) % 6

         =( (mod' * 10) % 6 + 0 % 6) % 6

         = (mod'*10 + 0) % 6;  //即当前层的mod=前一层的mod*10 + 0 (具体是0还是1和i有关) 因为0、1是循环取的

为了加强理解,再推导一遍i为奇数的过程

  前一层:mod =  (11*10 + 0)%6 = 2, k = 110, i = 6, k % 6 = 2

  后一层:  mod = (k'*10 + 1)  % 6   //此层 k = 110*10+1, i 为6*2+1

          = ( (k'%6 * 10%6) % 6 + 1 % 6) % 6

          = ( mod' * 10 + 1) % 6  //即当前层的mod=前一层的mod*10 + 1(具体是0和1和i有关)

这样就化简了求模的过程,共经过i步求模获得当前的目标数k % n = 0(但此时并不知道k具体的值),只知道求mod的过程

要通过操作数获取k,我是这样理解的:

  经过i步得到满足条件的数k(尽管k暂时还不知道), 由于每个数会产生两个分支,即k是由 i / 2 层的数k'递推而来的。 即 k'/2 * 2 + 0或1. 因此要知道k的末位是0还是1只要考虑当前k的奇偶性,因为2 * i / 2一定是偶数,奇偶性就是由后面的1或者0来决定的!如果是奇数,则证明当前k的最后一位是1,否则是0,值得注意的是:k的奇偶性和i的奇偶性恰巧是相同的,由于每个数会产生两个新的数字,可以看成是一棵二叉树, 如图:

结点编号即为获取当前k(括号里的数)所需要的操作步数,可以看到k与编号的奇偶性是恰好相同的,因此利用操作步数i, 循环i%2 与i/ = 2 就可以获取目标数的各个位(注意是从叶子到根得到的各个位置上的数(即先得到后面的位的数),因此输出时需要到过来),

优化后的BFS的代码:

  1. /* POJ 1426 Find The Multiple BFS 优化*/
  2. #include <cstdio>
  3.  
  4. int mod[]; //寸模,参考别人的计算这是最小的AC下限
  5.  
  6. int main()
  7. {
  8. int n;
  9. while (scanf("%d", &n) == && n){
  10. mod[] = ;
  11. int i;
  12. for (i = ; mod[i - ] != ; ++i){
  13. //该公式前面已证明, 注意:i为奇偶数分别对应 i%2 = 1和0
  14. mod[i] = (mod[i/] * + i % ) % n; // i/2为前一层
  15. }
  16. --i; //i此时为取模的次数
  17. int p = ;
  18. while (i){
  19. mod[p++] = i % ; //操作次数转化成所要的数--->k(可用二叉树理解)
  20. i /= ;
  21. }
  22. while (p){
  23. printf("%d", mod[--p]); //逆序输出即为目的数
  24. }
  25. printf("\n");
  26. }
  27.  
  28. return ;
  29. }

解法三: 这题还可以用DFS通过控制递归深度直接过

  1. /* POJ 1426 Find The Multiple --- DFS */
  2. #include <cstdio>
  3.  
  4. int n;
  5. bool flag;
  6.  
  7. void dfs(unsigned long long tmp, int i){
  8. if (flag || i > )
  9. return;
  10. if (tmp % n == ){
  11. flag = ;
  12. printf("%llu\n", tmp);
  13. return ;
  14. }
  15. else{
  16. dfs(tmp * , i+);
  17. dfs(tmp * + , i+);
  18. }
  19. }
  20.  
  21. int main()
  22. {
  23. while (scanf("%d", &n) == && n){
  24. flag = ;
  25. dfs(,);
  26. }
  27.  
  28. return ;
  29. }

POJ 1426 Find The Multiple --- BFS || DFS的更多相关文章

  1. POJ 1426 Find The Multiple (DFS / BFS)

    题目链接:id=1426">Find The Multiple 解析:直接从前往后搜.设当前数为k用long long保存,则下一个数不是k*10就是k*10+1 AC代码: /* D ...

  2. poj 1426 Find The Multiple (bfs 搜索)

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18012   Accepted: 729 ...

  3. POJ - 1426 Find The Multiple 【DFS】

    题目链接 http://poj.org/problem?id=1426 题意 给出一个数 要求找出 只有 0 和 1 组成的 十进制数字 能够整除 n n 不超过 200 十进制数字位数 不超过100 ...

  4. POJ 1426 Find The Multiple (dfs??!!)

    Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose ...

  5. POJ 1426 Find The Multiple BFS

    没什么好说的 从1开始进行广搜,因为只能包涵0和1,所以下一次需要搜索的值为next=now*10 和 next=now*10+1,每次判断一下就可以了,但是我一直不太明白我的代码为什么C++提交会错 ...

  6. poj 1426 Find The Multiple ( BFS+同余模定理)

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18390   Accepted: 744 ...

  7. DFS/BFS(同余模) POJ 1426 Find The Multiple

    题目传送门 /* 题意:找出一个0和1组成的数字能整除n DFS:200的范围内不会爆long long,DFS水过~ */ /************************************ ...

  8. POJ.1426 Find The Multiple (BFS)

    POJ.1426 Find The Multiple (BFS) 题意分析 给出一个数字n,求出一个由01组成的十进制数,并且是n的倍数. 思路就是从1开始,枚举下一位,因为下一位只能是0或1,故这个 ...

  9. POJ 1426 Find The Multiple(寻找倍数)

    POJ 1426 Find The Multiple(寻找倍数) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 Given ...

随机推荐

  1. <转>提高iOS开发效率的方法和工具

    介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的ID ...

  2. CCNA 4.14 TP Correction

    All people seem to need data processing ( Application presentation session transport network data li ...

  3. 纯JS文本在线HTML编辑器KindEditor

    KindEditor(http://www.kindsoft.net)是一款比较专业,主流,好用的在线HTML编辑器. 它除了可以将文本进行编辑.将Word中的内容复制进来外,本身还可以拖动缩放(右下 ...

  4. [VMware WorkStation]虚拟机网络

    桥接模式下复制物理网络连接: 复制物理网卡连接状态,就是说把你指定的.本机的.真是网卡的状态信息复制给虚拟机的虚拟网卡,比如说你的本机真是网卡链接到了家用路由器的LAN口上,获得到了DHCP分配的地址 ...

  5. .net 小技巧

    简单提示效果: <input runat="server" type="text" id="SelPerson" value=&quo ...

  6. HDFS的可靠性

    HDFS的可靠性 1.冗余副本策略   2.机架策略    3.心跳机制    4.安全模式 5.校验和           6.回收站       7.元数据保护    8.快照机制 1.冗余副本策 ...

  7. iOS中类方法的作用

    类方法,这意味着你将它发送给类,而不是对象实例. 因为不是发送给一个实例,所以你不能使用任何实例变量,你只能做一些通用性的事情. 实际上类方法只用于两种情况: 1.创建事物,比如创建一个特殊格式的字符 ...

  8. 2013年8月份第2周51Aspx源码发布详情

    上班族网站(毕设)源码  2013-8-16 [VS2010]源码描述:自己做的毕业设计,上班族网站项目是专门针对上班族群体设计和开发的网站项目.该网站主要涵盖了论坛平台,笑话模块,名言模块,资讯模块 ...

  9. tip use view.isineditmode() in your custom views to skip code when shown in eclipse

    tip use view.isineditmode() in your custom views to skip code when shown in eclipse

  10. Chapter 1: A Simple Web Server

    这算是一篇读书笔记,留着以后复习看看. Web Server又称为Http Server,因为它使用HTTP协议和客户端(一般是各种各样的浏览器)进行通信. 什么是HTTP协议呢? HTTP协议是基于 ...