Multiple
Time Limit: 1000MS | Memory Limit: 32768K |
Total Submissions: 5911 | Accepted: 1284 |
Description
a program that, given anatural number N between 0 and 4999 (inclusively), and M distinct decimaldigits X1,X2..XM (at least one), finds the smallest strictly positive multipleof N that has no other digits besides X1,X2..XM (if such a multiple exists).
Input
The input has several datasets separated by an empty line, each data set having the following format:
On the first line - the number N
On the second line - the number M
On the following M lines - the digits X1,X2..XM.
Output
For each data set, the programshould write to standard output on a single line the multiple, if such amultiple exists, and 0 otherwise.
An example of input and output:
Sample Input
22
3
7
0
1
2
1
1
Sample Output
110
0
Source
题目大意:
给定一个数N(0<=N<=4999),现在给定若干个十进制的数,能否用给定的十进制的数组成一个数,使其是N的倍数,如果存在,请求出倍数最小的数,如果不存在,请输出0;
十进制的数可以无限次重复使用,例如N=22;用7,0,1三个十进制的数可以组成110使其是22的最小的倍数;
该题必须解决两个问题:
1, 怎么判断不存在该数的倍数,也就是说在什么情况下可以停止遍历;
2, 因为数的可能大小非常大,我们不能用int来存储,那么需要怎么解决这个问题;
3, 如何保证取出的数是最小的额
取余数操作,从个位数开始,对每个数取余,若余数不为零,那么对每个余数添加增加所有的可能性,依次无线循环;何时结束呢?就是取余的时候,如果发现该余数已经是第二次出现了,那么可以丢弃,因此也就是说,最多需要遍历4999次,把所有的余数都取了一遍;
存数,我们可以用数组来存储每一位数,不妨新建一个类,每一种组合新建一个类;类包含成员prev,指向上一个数,打个比方,首次遍历 分别为数1,7新建一个类,他们的prev指向空,数1又能衍生出3个类,数1,0,7,此时他们的prev分别指向数1;同时也要有成员modNum保存当前的余数,也要有一个成员currentNum表示当前的数是多少。
为了保证取出的数是最小的,我们给这些十进制的数排序,每次取数从小开始取数,因为是fifo队列,所以总是从最小的计算;
开始动手写代码吧。。。
Java代码如下:
import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
// 用来标记所有的余数,比如余数32,可以表示allModNum[32]=1;表示已经存在
private int[] allModNum;
// 这是存放十进制数的数组;
private int[] number;
private int N;
public Main(int N) {
this.N = N;
if (N != 0) {
allModNum = new int[N];
Arrays.fill(allModNum, 0);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int N ;
while (cin.hasNext()) {
N = cin.nextInt();
Main ma = new Main(N);
int countNum;
countNum = cin.nextInt();
ma.number = new int[countNum];
for (int i = 0; i < countNum; i++) {
ma.number[i] = cin.nextInt();
}
ma.processItBfsAndPrint();
}
}
private void processItBfsAndPrint() {
// TODO Auto-generated method stub
// 辅助实现的队列;
LinkedList<Node> al = new LinkedList<Node>();
Arrays.sort(number);
// 这个事特例哈;
if (N == 0) {
System.out.println(0);
return;
}
Arrays.fill(allModNum, 0);
if (number[0] != 0) {
if (number[0] % N == 0) {
System.out.println(number[0]);
return;
}
al.add(new Node(null, number[0] % N, number[0]));
allModNum[number[0] % N] = 1;
}
for (int i = 1; i < number.length; i++) {
if (number[i] % N == 0) {
System.out.println(number[i]);
return;
}
al.add(new Node(null, number[i] % N, number[i]));
allModNum[number[i] % N] = 1;
}
Node nodetemp;
int modTemp;
while (al.size() > 0) {
nodetemp = al.remove();
for (int i = 0; i < number.length; i++) {
modTemp = (nodetemp.modNum * 10 + number[i]) % N;
// 这就是我们需要的值;
if (modTemp == 0) {
// 用来暂时保存所有的值
ArrayList<Integer> ans = new ArrayList<Integer>();
ans.add(number[i]);
while (nodetemp != null) {
ans.add(nodetemp.currentNum);
nodetemp = nodetemp.prev;
}
for (int j = ans.size() - 1; j >= 0; j--) {
System.out.print(ans.get(j));
}
System.out.println();
return;
}
if (allModNum[modTemp] == 0) {
allModNum[modTemp] = 1;
al.add(new Node(nodetemp, modTemp, number[i]));
}
}
}
System.out.println(0);
}
static class Node {
private Node prev;
private int modNum;
private int currentNum;
public Node(Node prev, int modNum, int currentNum) {
this.prev = prev;
this.modNum = modNum;
this.currentNum = currentNum;
}
}
}