There are tons of problems about integer multiples. Despite the fact that the topic is not original, the content is highly challenging. That’s why we call it “Yet Another Multiple Problem”.
In this problem, you’re asked to solve the following question: Given a positive integer n and m decimal digits, what is the minimal positive multiple of n whose decimal notation does not contain any of the given digits?
Input
There are several test cases.
For each test case, there are two lines. The first line contains two integers n and m (1 ≤ n ≤ 104). The second line contains m decimal digits separated by spaces.
Input is terminated by EOF.
Output
For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) while Y is the minimal multiple satisfying the above-mentioned conditions or “-1” (without quotation marks) in case there does not exist such a multiple.
Sample Input
2345 3
7 8 9
100 1
0
Sample Output
Case 1: 2345
Case 2: -1
Source
2012 Asia Chengdu Regional Contest
Recommend
liuyiding
题目分析:接触到这道题目时,我和队友们想的暴力一倍倍的加上去,然后加个卡时,结果一遍又一遍的超时、wrong answer,现在想想,觉得当时好傻,非常不理智。
这题的主要思想是bfs,将可以使用的数字按字典序最小的顺序bfs,直到搜出能整除n的数。裸bfs的话无疑会超时的,我们发现,n是小于10000的,
也就是说对n取余后的数也是小于10000的,这方面是否可以做点文章呢,其实,如果两个数对n取余的余数是一样的话,那个大一点的数完全没有考虑的必要了,则可以用一个bool型数组记录所得的余数,这样扩展的节点大概是10000左右,效率大幅度提高,174ms AC,题目给的20000ms太浪费了,呵呵。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
struct
{
int r; //当前节点的余数
int f; //当前节点的父指针
char c;//当前节点余数的最后一位
} q[10005],tmp;
void print(int k)
{
if (q[k].f!=-1)
{
print(q[k].f);
}
printf ("%c",q[k].c);
}
int main()
{
int n,m,x,l,r,res,i;
bool vis[10],p[10005];
int CASE=1;
while (~scanf("%d%d",&n,&m))
{
memset(vis,true,sizeof(vis));
while (m--)
{
scanf("%d",&x);
vis[x]=false;
}
l=1; r=0;
res=0;
memset(p,false,sizeof(p));
for (i=1;i<10;i++)
if (vis[i]&& !p[i%n])
{
r++;
p[i%n]=true;
q[r].c=i+'0';
q[r].r=i%n;
q[r].f=-1;
if (i%n==0)
{
res=r;
break;
}
}
while (l<=r&& !res)
{
for (i=0;i<10;i++)
if (vis[i])
{
tmp.c=i+'0';
tmp.r=(q[l].r*10+i)%n;
tmp.f=l;
if (!p[tmp.r])
{
r++;
q[r]=tmp;
p[tmp.r]=true;
if (tmp.r==0)
{
res=r;
break;
}
}
}
l++;
}
if (! res) printf("Case %d: -1\n",CASE++);
else
{
printf("Case %d: ",CASE++);
print(res);
printf("\n");
}
}
return 0;
}