dreamxr
精诚所至,金石为开!

导航

 

题目描述

  给定一个数n,以及几个数字,求仅包含给定数字的n的最小倍数.

分析

  bfs,先将数字升序排序,然后bfs,这样可以保证第一个满足条件的肯定是最小的.求出每次加入的数除以n的余数,如果该数出现过,就不用加入队列了.

因为n<5000,所以这个队列最多不会超个4999个元素...

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5010
using namespace std;
struct node{
    int pre,r,d;//pre前趋,r当前余数,d当前位的数字
};
bool cmp(int a,int b){
    return a<b;
}
node queue[N];
int digit[N],n,m;
bool hash[N];
void out(int head){
    if(head==-1)return;
    out(queue[head].pre);
    printf("%d",queue[head].d);
}
void bfs(){
    memset(hash,0,sizeof(hash));
    int head,tail;
    head=tail=0;
    for(int i=0;i<m;i++){
        if(digit[i]==0)continue;
        node p;
        p.pre=-1;
        p.d=digit[i];
        p.r=digit[i]%n;
        queue[tail++]=p;
    }
    while(head<tail){
        node p=queue[head],q;
        if(p.r==0){
            out(head);
            puts("");
            return;
        }
        for(int i=0;i<m;i++){
            q.d=digit[i];
            q.pre=head;
            q.r=(p.r*10+digit[i])%n;
            if(!hash[q.r]){
                queue[tail++]=q;
                hash[q.r]=1;
            }
        }
        head++;
    }
    puts("0");
    return;
}
int main(){
    while(~scanf("%d",&n)){
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            scanf("%d",&digit[i]);
        sort(digit,digit+m,cmp);
        if(n==0){
            puts("0");
            continue;
        }
        bfs();
    }
    return 0;
}
posted on 2012-08-30 00:00  dreamxr  阅读(267)  评论(0)    收藏  举报