zoukankan      html  css  js  c++  java
  • Yet Another Multiple Problem(bfs好题)

    Yet Another Multiple Problem

    Time Limit : 40000/20000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other)
    Total Submission(s) : 2   Accepted Submission(s) : 1
    Problem Description
    There are tons of problems about integer multiples. Despite the fact that the topic is not original, the content is highly challenging. That’s why we call it “Yet Another Multiple Problem”.
    In this problem, you’re asked to solve the following question: Given a positive integer n and m decimal digits, what is the minimal positive multiple of n whose decimal notation does not contain any of the given digits?
     
    Input
    There are several test cases. For each test case, there are two lines. The first line contains two integers n and m (1 ≤ n ≤ 10[sup]4[/sup]). The second line contains m decimal digits separated by spaces. Input is terminated by EOF.
     
    Output
    For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) while Y is the minimal multiple satisfying the above-mentioned conditions or “-1” (without quotation marks) in case there does not exist such a multiple.
     
    Sample Input
    2345 3 7 8 9 100 1 0
     
    Sample Output
    Case 1: 2345 Case 2: -1
     题意:就是给你一个n,让找出不含接下来m个数字能组成的n的倍数的最小解;参考了大神的写法;
    /***************/

    按照数的位数BFS,从小向大枚举就可以保证构造出来的数是递增的,如果不加判断就直接搜索的话,复杂度非常高。因此需要剪枝。

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

    因此我们只需要维护组合出来的数%N的值即可,如果在搜索的途中出现了相同的%N值,就可以直接忽略了,因为肯定没有前面的优秀。

    /***************/

    代码:
     1 #include<stdio.h>
     2 #include<string>
     3 #include<queue>
     4 #include<string.h>
     5 #include<algorithm>
     6 #define mem(a) memset(a,0,sizeof(a))
     7 using namespace std;
     8 const int MAXN=1e4+10;
     9 int vis[MAXN],del[MAXN],pre[MAXN];
    10 char al[MAXN];
    11 int n;
    12 void print_ans(){
    13     int r=0;
    14     string ans;
    15     while(ans.empty()||r!=0){
    16         ans+=al[r];
    17         r=pre[r];//由于anser的下属是0,刚开始的数字的上司又是0,所以最后找到0结束循环; 
    18     }
    19     reverse(ans.begin(),ans.end());
    20     puts(ans.c_str()); 
    21 }
    22 bool bfs(){
    23     queue<int>dl;
    24     dl.push(0);
    25     while(!dl.empty()){
    26         int f1,f2;
    27         f1=dl.front();//**
    28         dl.pop();
    29         for(int i=0;i<=9;i++){
    30             if(del[i]||i==0&&f1==0)continue;
    31             f2=(f1*10+i)%n;
    32             if(vis[f2])continue;//应该放上面 
    33             pre[f2]=f1;//**
    34             al[f2]=i+'0';
    35             if(f2==0){
    36                 print_ans();
    37                 return true;
    38             }
    39             vis[f2]=1;
    40             dl.push(f2);
    41         }
    42     }
    43     puts("-1");
    44     return false;
    45 }
    46 int main(){
    47     int m,flot=0;
    48     while(~scanf("%d%d",&n,&m)){
    49         mem(vis);mem(del);mem(pre);mem(al);
    50         while(m--){
    51             int temp;
    52             scanf("%d",&temp);
    53             del[temp]=true;
    54         }
    55         printf("Case %d: ",++flot);
    56         bfs();
    57     }
    58     return 0;
    59 }

     第二种方法wa:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=1e4+10;
     7 int num[20];
     8 struct Node{
     9     int s[100];
    10     int len;
    11 };
    12 int M,C,N;
    13 int vis[MAXN];
    14 int mod(Node a){
    15     int x=0;
    16     for(int i=0;i<a.len;i++){
    17         x=(x*C+a.s[i])%N;
    18     }
    19     return x;
    20 }
    21 void print_ans(Node a){
    22     for(int i=0;i<a.len;i++){
    23         printf("%d",a.s[i]);
    24     }
    25     puts("");
    26 }
    27 void bfs(){
    28     memset(vis,0,sizeof(vis));
    29     queue<Node>dl;
    30     Node a;
    31     a.len=1;
    32     int md;
    33     for(int i=0;i<M;i++){
    34         a.s[0]=num[i];
    35         md=mod(a);
    36         if(vis[md]||num[i]==0)continue;
    37         if(md==0&&num[i]){
    38             printf("%d
    ",num[i]);
    39             return;
    40         }
    41         vis[md]=1;
    42         dl.push(a);
    43     }
    44     while(!dl.empty()){
    45         a=dl.front();
    46         dl.pop();
    47     for(int i=0;i<M;i++){
    48         if(a.len==1&&a.s[0]==0)continue;
    49         a.s[a.len]=num[i];
    50         a.len++;
    51         md=mod(a);
    52     if(vis[md]){
    53         a.len--;
    54         continue;
    55     }
    56         if(md==0){
    57             
    58             print_ans(a);
    59             return;
    60         }
    61         vis[md]=1;
    62         dl.push(a);
    63         a.len--;
    64         }
    65     }
    66     puts("-1");
    67 }
    68 int main(){
    69     int del[20],flot=0;
    70     while(~scanf("%d%d",&N,&M)){
    71         memset(del,0,sizeof(del));
    72         for(int i=0;i<M;i++){
    73             int temp;
    74             scanf("%d",&temp);
    75             del[temp]=1;
    76         }
    77         int i,j;
    78         for(i=0,j=0;i<=9;i++){
    79             if(!del[i])num[j++]=i;
    80         }
    81         M=j;
    82         printf("Case %d: ",++flot);
    83         C=10;
    84         bfs();
    85     } 
    86     return 0;
    87 }
  • 相关阅读:
    grub.conf文件说明
    grub手动引导win7
    手动grub引导redhat
    grub的三种安装方式
    试题系列五(公鸡5元一只,母鸡3元一只,小鸡1元3只,求100元刚好买100只鸡的可能)
    试题系列四(袋中有6红球 3黄球 3绿球,从中取6个球,求所有拿到球的颜色的可能 c(12,6))
    试题系列三(求任意两个数的最大公约数)
    试题系列二(求1000内的完数)
    试题系列一(求4,5,6,7所有四位数的排列组合)
    pthread_cleanup_push和pthread_cleanup_pop清除函数是否执行的说明
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4864836.html
Copyright © 2011-2022 走看看