zoukankan      html  css  js  c++  java
  • HDU4474_Yet Another Multiple Problem

    题意很简单,要你用一些数字,组成一个数的倍数,且那个数最小。

    比赛的时候没能做出来,深坑啊。

    其实我只想说我以前就做过这种类型的题目了,诶。

    题目的解法是数位宽搜

    首先把可用的数位提取出来,从小到大一个一个放到后面去。这样保证了出现的数字一定是最小的。

    同时记录出现过的余数的情况,因为同一个余数k*10+ai再对n取余的数是相同的,所以对于同一个余数我们不需要走两遍,这样就保证了搜索的时间复杂度为O(n)。

    我们只要对于每一个状态,直接枚举可选择的数字放在他们后面,直到找到一个余数为0的就可以停止了。

    总的时间复杂度为O(n*10),因为后面最多可能有10个数可以放上面嘛。。。。

    对于深搜的每一个状态只要用一个数字和一个前趋节点就可以了,输出的时候递归输出,因为每一个状态都是由前面的状态推过来的嘛。

     

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define maxn 10010
     5 using namespace std;
     6 
     7 int pre[maxn],s[maxn];
     8 char q[maxn];
     9 bool res[maxn];
    10 bool b[10];
    11 int a[10],N,n,m,k,t1,t2,cur;
    12 
    13 void output(int pos)
    14 {
    15     if (pre[pos]>0) output(pre[pos]);
    16     printf("%d",(int)q[pos]);
    17 }
    18 
    19 void bfs()
    20 {
    21     if (n==0)
    22     {
    23         if (b[0]) printf("0
    ");
    24         else printf("-1
    ");
    25         return;
    26     }
    27     t1=t2=0;
    28     memset(res,false,sizeof res);
    29     for (int i=1; i<=9; i++)
    30         if (b[i]) q[++t2]=i,pre[t2]=0,s[t2]=i%n,res[i%n]=true;
    31     while (t1<t2)
    32     {
    33         if (s[++t1]==0)
    34         {
    35             output(t1);
    36             printf("
    ");
    37             return;
    38         }
    39         for (int i=1; i<=N; i++)
    40             if (res[(s[t1]*10+a[i])%n]==false)
    41             {
    42                 t2++;
    43                 s[t2]=(s[t1]*10+a[i])%n;
    44                 res[s[t2]]=true;
    45                 q[t2]=a[i];
    46                 pre[t2]=t1;
    47             }
    48     }
    49     printf("-1
    ");
    50 }
    51 
    52 int main()
    53 {
    54     int cas=0;
    55     while (scanf("%d%d",&n,&m)!=EOF)
    56     {
    57         for (int i=0; i<=9; i++) b[i]=true;
    58         N=0;
    59         while (m--) scanf("%d",&k),b[k]=false;
    60         for (int i=0; i<=9; i++) if (b[i]) a[++N]=i;
    61         printf("Case %d: ",++cas);
    62         bfs();
    63     }
    64     return 0;
    65 }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    Intern Day15
    Intern Day15
    Intern Day15
    Intern Day15
    Intern Day15
    Intern Day14
    Intern Day14
    纯CSS序列号
    屌丝、高富帅、文艺青年、土豪的区别
    什么是文艺
  • 原文地址:https://www.cnblogs.com/lochan/p/3402714.html
Copyright © 2011-2022 走看看