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


posted @ 2016-07-11 14:39  _Wilbert  阅读(136)  评论(0编辑  收藏  举报