zoukankan      html  css  js  c++  java
  • hdu4474 2012 Asia Chengdu Regional Contest 数位bfs+同余剪枝+模数化约

     1 #include<iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 using namespace std;
     5 struct Node
     6 {
     7     int r;//余数
     8     int f;//父亲节点
     9     int n;//数字
    10     Node(){};
    11     Node(int r1,int f1,int n1){r=r1;f=f1;n=n1;}
    12 }node[10010<<2];
    13 int d[11];
    14 bool rem[11000];
    15 int n,m;
    16 void print(int f)
    17 {
    18     if (node[f].f!=-1) print(node[f].f);
    19     printf("%d",node[f].n);
    20 //    if ( f == -1 ) return;
    21 //    print( node[f].f );
    22 //    printf( "%d", node[f].n );
    23 }
    24 int bfs()
    25 {
    26     memset(rem,0,sizeof(rem));
    27     int head=1;int tail=0;
    28     for(int i=1;i<=9;i++)//首位不可以为0;
    29     {
    30         if(d[i]) continue;
    31         int r=i%n;
    32         if(rem[r]) continue;
    33         node[++tail]=Node(r,-1,i);rem[r]=true;
    34         if (r==0) return tail;
    35     }
    36     while(head<=tail)//一开始等号没写,一直w
    37     {
    38         Node k=node[head];
    39         for(int i=0;i<10;i++)
    40         {
    41             if (d[i]) continue;
    42             int r=(k.r*10+i)%n;
    43             if (rem[r]) continue;
    44             node[++tail]=Node(r,head,i);
    45             rem[r]=true;
    46             if (r==0) return tail;
    47         }
    48         head++;
    49     }
    50     return -1;
    51 }
    52 int main()
    53 {
    54     int cas=0;
    55     while(~scanf("%d%d",&n,&m))
    56     {
    57         memset(d,0,sizeof(d));
    58         for(int i=0;i<m;i++)
    59         {
    60             int k;
    61             scanf("%d",&k);
    62             d[k]=1;
    63         }
    64         printf("Case %d: ",++cas);
    65         int ans=bfs();//找到答案则返回最后底层节点的序号
    66         if (ans==-1) printf("-1
    ");else {print(ans);printf("
    ");}
    67     }
    68     return 0;
    69 }
    View Code

    题目描述:给定一个数n,用0--9中的某几个数字组成任意正整数m,求解使m%n==0的最小的m,若m不存在,则输出-1.

    方法:

    1、暴力枚举n,2n,3n。。。判断是否由给定的几个数字组成,满足则输出。防止超时,限制枚举步数。

       分析:使用高精度,编码较复杂;枚举步数一直TLE或W,说明这个算法行不通

    2、标准方法:按数字从小到大bfs+bfs父节点存储+记忆化搜索记录简化余数计算+同余剪枝(最后的这个是剪枝的关键啊!!!)

    3、方法分述:

        (1)bfs()

         例如:用1、2、3 组成数

         拓扑结构:第一层:      1            2                 3

                       第二层:   1   2   3    1  2  3      1     2    3

        说穿了就是个满n叉树。。。。。

        有了拓扑结构图,我们建模就思路清晰了。

         (2)记录父节点

        开始我是用queue容器+指针的写法,实在是一直错,所以我就手写了"指针",以数组下标为地址,一一对应,这点在《入门经典》的图论一部分讲的很透彻,让我又复习了一遍。

         (3)记忆化搜索余数

          设父节点f,余数mf;子节点c,余mc,c的个位数为cn

          则 mc=(mf+cn)%n;这显然比高精度求余要优化指数级别= =

          (4)同余剪枝

          这个就属于数论里面的内容,描述如下:(waiting 拓展)

    4、代码描述:

        (1)使用了手写队列

        (2)注意 head<=tail 这个条件,在整个出入队列的过程中

    一个同样的数位bfs的问题:http://www.cnblogs.com/bvbook/archive/2009/02/06/1385448.html

  • 相关阅读:
    搭建nexus私服(maven)
    maven配置本地仓库(从本地仓库下载jar包到.m2仓库)
    关于引入多个jquery冲突的问题(附一个很好用的validate前端验证框架及使用方法)
    java excel导出
    Eclipse+Maven创建webapp项目 及部署在tomcat上
    solr添加IK分词和自己定义词库
    将Mysq数据导入solr索引库
    solr +zookeeper+Jetty 集群搭建
    solr +zookeeper+tomcat 集群搭建
    如何用Maven创建web项目(具体步骤)转载
  • 原文地址:https://www.cnblogs.com/little-w/p/3399011.html
Copyright © 2011-2022 走看看