题目大意:
给出一个整数M,和若干十进制数字 ,求由这些十进制数字组成的这个整数的最小倍数,
没有的话输出0.
解答:
最原始想法,从小到大枚举每个倍数,果断PASS.
正规想法,用给出的十进制数字由小到大生成一系列数,依次判断是否可行,
key point:由x生成若干数(由小到大):x*10+a1,......,x*10+an,不应全部加入队列,
仅当 (x*10+ap)%M 这个余数并未出现过 (1<=p<=n) 才加入队列,因为如果在
前面出现过这个余数,由前面生成的数得到的答案肯定比现在的小.所以最多枚举
M个数字.
注意答案可能非常非常大,应单独存储每位数字,用链表存起来,输出的时候递归输出.
还有STL中队列指针POP以后无法访问,要自己写一个队列.
#include<iostream>
#include<algorithm>
using namespace std;
struct Ans
{
int mod;//余数
int x;//十进制数字
Ans *pre;
Ans(int a,int b,Ans *c):mod(a),x(b),pre(c){}
Ans():pre(0){}
};
class Muliple
{
int x[10],n,num,front,last;
bool f[5009]; //代表余数是否在前面得出过
Ans ans[10];
Ans q[5009]; //BFS所用队列
void initial(); //初始化数据
void print(Ans *); //打印数据
public:
void work(int);
};
void Muliple::initial()
{
front=last=0;
cin>>n;
int i;
for(i=0;i<n;i++)
cin>>x[i];
memset(f,false,sizeof(f));
}
void Muliple::work(int _num)
{
num=_num;
initial();
if(num==0){cout<<"0"<<endl;return;}
sort(x,x+n);
int i;
for(i=0;i<n;i++)
{
ans[i].x=x[i];
ans[i].mod=x[i]%num;
ans[i].pre=NULL;
if(ans[i].mod!=0)f[ans[i].mod]=true;
}
for(i=0;i<n;i++)
if(ans[i].x!=0)q[last++]=ans[i];
while(front<last)
{
Ans &temp=q[front++]; //取队列首元素
if(temp.mod==0){print(&temp);cout<<endl;return;} //得到答案
for(i=0;i<n;i++)
{
int mod=(temp.mod*10+x[i])%num;
if(f[mod]==false){q[last++]=Ans(mod,x[i],&temp);f[mod]=true;} //余数未出现过则加入队列
}
}
cout<<"0"<<endl;
}
void Muliple::print(Ans *temp)
{
if(temp==NULL)return;
print(temp->pre);
cout<<temp->x;
}
Muliple M;
int main()
{
int num;
while(cin>>num)
{
M.work(num);
}
return 0;
}