POJ 1465【Multiple】

悠悠 2021-11-10 08:26 311阅读 0赞

描述

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:

输入输出样例

输入样例

  1. 22
  2. 3
  3. 7
  4. 0
  5. 1
  6. 2
  7. 1
  8. 1

输出样例

  1. 110
  2. 0

解题思路

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

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

题解1

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

题解2

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

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 int n,m,sum=0;
  4. 4 struct node{
  5. 5 int father;//父节点
  6. 6 int ans;//数值
  7. 7 }fa[10001];
  8. 8 int num[500005];
  9. 9 bitset<5000> flag;//bool
  10. 10 queue<int> q;
  11. 11 void put(int x)
  12. 12 {
  13. 13 if(x==0)return;//到根节点了,返回
  14. 14 put(fa[x].father);//继续向前递归
  15. 15 cout<<fa[x].ans;//打印操作
  16. 16 }
  17. 17 void bfs()
  18. 18 {
  19. 19 int l=1,r=0;//类似于手写队列,但我还是用的队列
  20. 20 for(int i=1;i<=m;i++)
  21. 21 {
  22. 22 if(num[i]!=0)//避免前导零
  23. 23 {
  24. 24 q.push(num[i]%n);
  25. 25 flag[num[i]%n]=1;//余数存储
  26. 26 r++;//
  27. 27 fa[r].father=0;//根节点
  28. 28 fa[r].ans=num[i];//记录数字
  29. 29 }
  30. 30 }
  31. 31 while(!q.empty())
  32. 32 {
  33. 33 int head=q.front();
  34. 34 q.pop();
  35. 35 if(head==0)
  36. 36 {
  37. 37 put(l);//输出
  38. 38 return;
  39. 39 }
  40. 40 for(int i=1;i<=m;i++)
  41. 41 {
  42. 42 int t=head;
  43. 43 t=(t*10+num[i])%n;//继续取余
  44. 44 if(!flag[t])
  45. 45 {
  46. 46 r++;//新建节点
  47. 47 flag[t]=1;//标记
  48. 48 fa[r].ans=num[i];//记录数字
  49. 49 fa[r].father=l;//记录father,也就是扩展它的节点的编号
  50. 50 q.push(t);
  51. 51 }
  52. 52 }
  53. 53 l++;
  54. 54 }
  55. 55 cout<<0;//没找到
  56. 56 }
  57. 57 int main()
  58. 58 {
  59. 59 cin>>n>>m;
  60. 60 for(int i=1;i<=m;i++)
  61. 61 {
  62. 62 scanf("%d",&num[i]);//输入
  63. 63 }
  64. 64 if(n==0)//特判
  65. 65 {
  66. 66 cout<<0;
  67. 67 return 0;
  68. 68 }
  69. 69 sort(num+1,num+1+m);//排序
  70. 70 bfs();
  71. 71 }

转载于:https://www.cnblogs.com/hualian/p/11189568.html

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读