zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }


  • 相关阅读:
    NIO 学习笔记
    Spring Boot 学习笔记
    Java集合框架
    StringBuffer&StringBuilder类
    String 类
    Java 重写 hashCode() 和 equals() 方法
    Java 基本数据类型 && 位运算
    [SequenceFile_1] Hadoop 序列文件
    Windows 下端口被占用
    Java 反射机制
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179468.html
Copyright © 2011-2022 走看看