zoukankan      html  css  js  c++  java
  • POJ 1465【Multiple】

    描述

    a program that, given a natural number N between 0 and 4999 (inclusively), and M distinct decimal digits X1,X2..XM (at least one), finds the smallest strictly positive multiple of N that has no other digits besides X1,X2..XM (if such a multiple exists).

    The input file has several data sets separated by an empty line, each data set having the following format:

    给你一个数字N,0<=N<=4999
    再给一个数字M,代表接下来会给你M类不同的数字
    希望你找出一个N的倍数出来,这个值仅由给定的M类数字构成,不包含其它的数字
    希望这个N的倍数的值越小越好,如果无解输出0

    输入输出格式

    输入

    On the first line - the number N
    On the second line - the number M
    On the following M lines - the digits X1,X2..XM.

    输出

    For each data set, the program should write to standard output on a single line the multiple, if such a multiple exists, and 0 otherwise.

    An example of input and output:

    输入输出样例


    输入样例

    22
    3
    7
    0
    1
    
    2
    1
    1

    输出样例

    110
    0 
    

    解题思路

      本来呢,我开了个long long来存每次搜到的数,但是交上去,超空间???所以,机智的我用字符串来存,再写一个取余函数,边加边余,果然方便多了。然后这道题要特判0的情况,并且避免出现0000的情况,最后就出来了。

      然后本题有一个剪枝的操作:举一个例子,因为36%24=12=60%24,所以36****%24=60****%24.所以我们搜到36时,记录余数,下次遇到60直接跳过就行。

    题解1

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m;
     4 int x[10001];
     5 bool flag[10001];
     6 int MOD(string s)//取余函数 
     7 {
     8     int ans=0;
     9     for(int i=0;i<s.size();i++)
    10     {
    11         ans=(ans*10+s[i]-'0')%n;//边加边余 
    12     }
    13     return ans;
    14 }
    15 string bfs()
    16 {
    17     memset(flag,0,sizeof(flag));//初始化 
    18     queue<string> q;//队列 
    19     for(int i=1;i<=m;i++)
    20     {
    21         q.push(string(1,x[i]+'0'));//string(num,char)构造函数,转成字符串形式 
    22     }
    23     while(!q.empty())
    24     {
    25         string head=q.front();
    26         q.pop();
    27         if(head!="0"&&MOD(head)==0)//是倍数并且不是0 
    28         {
    29             return head;//返回 
    30         }
    31         for(int i=1;i<=m;i++)
    32         {
    33             string ans=head;
    34             if(ans=="0"&&x[i]==0)continue;//避免00000 
    35             ans+=string(1,x[i]+'0');//加上去 
    36             if(!flag[MOD(ans)])//剪枝操作 
    37             {
    38                 flag[MOD(ans)]=true;//标记 
    39                 q.push(ans);
    40             }
    41             else continue;
    42         }
    43     }
    44     return "0";//没找到 
    45 }
    46 int main()
    47 {
    48     while(cin>>n>>m)//循环输入 
    49     {
    50         for(int i=1;i<=m;i++)
    51         {
    52             cin>>x[i];
    53         }
    54         if(n==0)//特判 
    55         {
    56             cout<<0<<endl;
    57             continue;
    58         }
    59         sort(x+1,x+1+m);//排个序 
    60          cout<<bfs()<<endl;
    61     }
    62 } 

     题解2

      这个的队列我用的余数,代码自己看一下,最后输出我是用了一个fa数组一步一步递归往回,最后输出。(这个没有while输入)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,sum=0;
     4 struct node{
     5     int father;//父节点 
     6     int ans;//数值 
     7 }fa[10001];
     8 int num[500005];
     9 bitset<5000> flag;//bool 
    10 queue<int> q;
    11 void put(int x)
    12 {
    13     if(x==0)return;//到根节点了,返回 
    14     put(fa[x].father);//继续向前递归 
    15     cout<<fa[x].ans;//打印操作 
    16 }
    17 void bfs()
    18 {
    19     int l=1,r=0;//类似于手写队列,但我还是用的队列 
    20     for(int i=1;i<=m;i++)
    21     {
    22         if(num[i]!=0)//避免前导零 
    23         {
    24             q.push(num[i]%n);
    25             flag[num[i]%n]=1;//余数存储 
    26             r++;//
    27             fa[r].father=0;//根节点 
    28             fa[r].ans=num[i];//记录数字 
    29         }
    30     }
    31     while(!q.empty()) 
    32     {
    33         int head=q.front();
    34         q.pop();
    35         if(head==0)
    36         {
    37             put(l);//输出 
    38             return;
    39         }
    40         for(int i=1;i<=m;i++)
    41         {
    42             int t=head;
    43             t=(t*10+num[i])%n;//继续取余 
    44             if(!flag[t])
    45             {
    46                 r++;//新建节点 
    47                 flag[t]=1;//标记 
    48                 fa[r].ans=num[i];//记录数字 
    49                 fa[r].father=l;//记录father,也就是扩展它的节点的编号 
    50                 q.push(t);
    51             }
    52         }
    53         l++;
    54     }
    55     cout<<0;//没找到 
    56 }
    57 int main()
    58 {
    59     cin>>n>>m;
    60     for(int i=1;i<=m;i++)
    61     {
    62         scanf("%d",&num[i]);//输入 
    63     }
    64     if(n==0)//特判 
    65     {
    66         cout<<0;
    67         return 0;
    68     }
    69     sort(num+1,num+1+m);//排序 
    70     bfs();
    71 }
  • 相关阅读:
    产生6位的随机码
    用户输入注册的小程序
    进度条的小程序
    文件的相关操作---读写与修改
    字符串分割(C++) 转载
    C++ Stream与编码转换
    wxWidgets界面设计工具DialogBlocks(转载)
    WIN32窗口模板
    WTL对话框应用程序响应键盘消息
    常用网站
  • 原文地址:https://www.cnblogs.com/hualian/p/11189568.html
Copyright © 2011-2022 走看看