POJ 1465 Multiple

题目大意:

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


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值