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); } } }