POJ 1465 Multiple

来源:互联网 发布:linux修改ssh默认端口 编辑:程序博客网 时间:2024/06/13 01:38

题目大意:

给出一个整数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;}