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 }
原文地址:https://www.cnblogs.com/hualian/p/11189568.html