Multiple

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wastematerial/article/details/45693201
Description

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).

Input

The input has several data sets separated by an empty line, each data set having the following format:

On the first line - the number N
On the second line - the number M
On the following M lines - the digits X1, X2 ... XM.

Output

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.

Sample Input
22
3
7
0
1
2
1
1
Sample Output
110
0
这是一道广搜的题,即每一位都把这m个数去试试,每次放的时候都试试能否整除n就可以了,例如22,我们如果放了1 1 那么第三个数可以从0开始试(11*10+0)%22;
有个问题就是如果那个数的倍数很大的时候就可能不是int的范围甚至long long都不行,那就要用到了同余模定理
这题还有一个特殊例子点击打开链接
下面直接贴代码
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#define MAX 6000
using namespace std;
bool cmp(int x,int y)
{
    return x<y;
}
int a[20],book[MAX],ans[MAX];//book记录哪些余数是已经在队列中
int m,n;
struct node
{
    int x;
    int last;
    int mod;
}num[MAX];
void bfs()
{
    queue <int> q;//用队列记录哪些需要搜的
    int t=0;
    for(int i=0;i<m;i++)
    {
        if(a[i]==0)
            continue;
        num[t].x=a[i];
        num[t].last=-1;
        num[t].mod=a[i]%n;
        if(num[t].mod==0)//如果第一位直接是它的倍数就直接输出
        {
            printf("%d",num[t].x);
            return ;
        }
        book[num[t].mod]=1;
        q.push(t);
        t++;
    }
    while(!q.empty())
    {
        int j;
        j=q.front();
        q.pop();
        for(int i=0;i<m;i++)
        {
            int mm;
            mm=(num[j].mod*10+a[i])%n;
            if(mm==0)//余数为0便直接输出
            {
                int jj=0;
                ans[jj++]=a[i];
                while(num[j].last!=-1)
                {
                    ans[jj++]=num[j].x;
                    j=num[j].last;
                }
                ans[jj]=num[j].x;
                for(int ii=jj;ii>=0;ii--)
                    printf("%d",ans[ii]);
                return ;
            }
            if(book[mm]==0)//判断余数是否出现过在队中,如果出现过就不用进队,
                           //因为后面无论加上都不会出现余数是0的情况。
            {
                num[t].x=a[i];
                num[t].last=j;
                num[t].mod=mm;
                book[mm]=1;//标记
                q.push(t);//进队
                t++;
            }
        }
    }
    printf("0");
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            scanf("%d",&a[i]);
        memset(book,0,sizeof(book));
        if(n==0)//特判如果n是0就直接输出0
        {
            printf("0\n");
            continue;
        }
        sort(a,a+m,cmp);
        bfs();
        printf("\n");
    }
    return 0;
}
还有一种大神想出来的 点击打开链接
小白博客,望指教!!!

猜你喜欢

转载自blog.csdn.net/Wastematerial/article/details/45693201