AOJ-782 整倍数
Description
给定自然数N和十进制集合X={x1,x2,...,xm}(0< m <= 10),找出N的最小正整倍数,使得该倍数中包含的所有数字均位于几何X中。若在正整倍数的位数500位以内无法找到,则输出没有找到标志。
Input
输入包括多组测试数据,每组占两行,第一行为一个自然数N,1<=N<=9999;第二行中包括多个整数,其中第一个整数位M,1<=M<=10,接着后面有M个0-9的数字。当本组测试数据中第一行的数为0时,表示输入结束,并且后面没有其他数据,本组数据也不要处理。
Output
对每组测试数据输出一行结果。若在位数小于500的N的正整倍数中存在满足条件的数,则输出其中最小的正整倍数,若不存在,则输出没找到标志“No Found”
Sample Input
15 2 4 5 123 6 9 8 0 6 5 4 10 5 1 2 3 4 5 0
Sample Output
45 984 No Found
解题思路:
看到这个题目一开始我想的是找循环节,比如3的倍数,所出现的数字,在300之后就不会改变了,(事实上30之后就不会改变了),但是很可惜第一发wa了,想了想,发现对于最大的9999一开始写的上限小了,但是改大之后就会TLE,这样这个思路就不对了,后来知道了有种O(n)的搜索可以解决这个问题,我一开始是拒绝的,因为我想的是10^500次方,懵逼。。。不过仔细一想,我们来考虑一个问题,46 mod 8 = 6, 86 mod = 6,如果在46,86后面添加一位数字是什么样呢,463 mod 8 = 7, 863 mod 8 = 7,这样就看到一个结论了,如果两个数a、b对于n取模的结果相等,那么ax + c mod n == bx + c mod n这样,对于n的倍数其实不需要考虑500位,只需要考虑所有倍数对n取模在0-n-1的情况就行了,这样结果是O(n)的。代码如下,用java写的,没怎么优化。
import java.util.*;
import java.math.BigInteger;
import java.io.*;
public class Main {
private static Scanner in;
public static void bfs(int[] a, int m, int n){
String s = new String("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger Over = new BigInteger(s);
BigInteger N = BigInteger.valueOf(n);
Queue<BigInteger> q = new LinkedList<BigInteger>();
int[] vis = new int[n];
q.clear();
for(int i = 0; i < m; ++i){
if(vis[a[i] % n] == 0){
vis[a[i] % n] = 1;
q.add(BigInteger.valueOf(a[i]));
}
}
BigInteger p;
while((p = q.poll()) != null){
if(p.compareTo(Over) >= 0) break;
if(p.mod(N).equals(BigInteger.ZERO) && !p.equals(BigInteger.ZERO)){
System.out.println(p);
return;
}
for(int i = 0; i < m; ++i){
BigInteger t = p.multiply(BigInteger.valueOf(10)).add(BigInteger.valueOf(a[i]));
int nn = t.mod(N).intValue();
if(vis[nn] == 0 || nn == 0){
q.offer(t);
vis[nn] = 1;
}
}
}
System.out.println("No Found");
}
public static void main(String[] args){
// TODO Auto-generated method stub
in = new Scanner(new BufferedInputStream(System.in));
while(true){
int n = in.nextInt();
if(n == 0) break;
int m = in.nextInt();
int[] a = new int[m];
for(int i = 0; i < m; ++i){
a[i] = in.nextInt();
}
Arrays.sort(a);
bfs(a, m, n);
}
}
}

浙公网安备 33010602011771号