zoukankan      html  css  js  c++  java
  • hdu 4474 转化为bfs + 一个巧妙的剪枝~

    比赛的时候只想到的暴力枚举的方法 枚举n的倍数 但是不确定到哪里为止输出-1。看了题解其实可以转化为, 0-9这十个数字里面的若干个数字组合出一个数,使这个数是N的倍数,求最小的这个这样的数,不存在的话输出-1。这样地话就成了一道bfs的题目,再加一个很巧妙的剪枝,可以在规定时间求出。

    参考大神博客:http://blog.csdn.net/yang_7_46/article/details/12356587

    优化方法:如果一个数%N==0,那么这个数就是N的倍数。在没有找到的前提下,如果A%N==B%N,而且A<B,那么其实我们就可以取A而不取B,因为如果在A末尾增加C可以使得AC%N==0,那么BC%N也等于0,易得:如果A和B追加数之后%N==0,那么最优条件下追加的数肯定相同

    参考大神代码: http://www.cnblogs.com/wally/archive/2013/03/24/2978645.html

     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 const int N=10010;
     5 using namespace std;
     6 int n,m;
     7 int a[10];
     8 int pre[N],num[N];
     9 
    10 void print(int u)
    11 {
    12     if(pre[u]!=-1)print(pre[u]);//pre[]保存的是形成u的前一个结点,直到为-1;
    13     printf("%d",num[u]);//由于num[]保存的记录u的最后一个数字,应此应该逆序输出
    14 }
    15 
    16 void bfs()
    17 {
    18     queue<int>Q;
    19     for(int i=1; i<=9; i++)
    20         if(!a[i])
    21         {
    22             int t=i%n;
    23             if(t==0)
    24             {
    25                 printf("%d",i);
    26                 return ;
    27             }
    28             Q.push(t);
    29             num[t]=i;
    30         }
    31     while(!Q.empty())
    32     {
    33         int u=Q.front();
    34         Q.pop();
    35         for(int i=0; i<=9; i++)if(!a[i])
    36             {
    37                 int t=(u*10+i)%n;
    38                 if(num[t]==-1)
    39                 {
    40                     Q.push(t);//只存余数t  
    41                     pre[t]=u;//由于记录到达t的前一个结点u;
    42                     num[t]=i;//记录形成t的最后一位数字
    43                 }
    44                 if(t==0)
    45                 {
    46                     print(t);
    47                     return ;
    48                 }
    49             }
    50     }
    51     printf("-1");
    52 }
    53 
    54 
    55 int main()
    56 {
    57     int _case=1;
    58     while(~scanf("%d%d",&n,&m))
    59     {
    60         memset(a,0,sizeof(a));
    61         memset(pre,-1,sizeof(pre));
    62         memset(num,-1,sizeof(num));
    63         int x;
    64         while(m--)
    65         {
    66             scanf("%d",&x);
    67             a[x]=1;
    68         }
    69         printf("Case %d: ",_case++);
    70         bfs();
    71         printf("
    ");
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    canvas背景粒子动态变化动画
    点击屏幕弹出心形效果
    前端图片的性能优化
    vue的computed和method的区别
    es6的...
    命名路由和命名视图
    编程式路由
    [思维]蚂蚁感冒
    [模板]前缀树 / 字典树及应用
    [模板]三分搜索
  • 原文地址:https://www.cnblogs.com/assult/p/4027441.html
Copyright © 2011-2022 走看看