题目
题目描述
Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimalrepresentation contains only the digits 0 and 1. You may assume that n is not greater than 200 and thereis a corresponding m containing no more than 100 decimal digits.
输入
The input file may contain multiple test cases. Each line contains a value of n (1 < n < 200). A linecontaining a zero terminates the input.
输出
For each value of n in the input print a line containing the corresponding value of m. The decimarepresentation of m must not contain more than 100 digits. If there are multiple solutions for a givenvalue ofn, any one of them is acceptable.
样例输入
2
6
19
0
样例输出
10
1110
11001
解答
题目大意
给定正整数n,编写程序找出非零值n的倍数m,并且m的十进制数表示仅包含数字0 和 1。你可以假设n不大于 200,且有不超过 100 位的相应 m。
分析
本题乍看之下好像和宽度优先搜索无关,只需逐个测试n的倍数是否全由0和1组成即可,但这样做相当于枚举,需要枚举n在整个搜索空间(小于 100 位的整数)中的所有倍数,这个计算量非常大,因为逐个判断会花费大量时间,因此这种方法的效率非常低可以反过来想这个问题:只由0和1组成的数相比于整个搜索空间而言是非常少的,可以去搜索由0和1组成的数,然后通过判断这些数能否整除n来求解这个问题。于是,可将由0和1组成的数字 num 作为一个搜索状态。能由 num扩展得到的状态有两个,一个是 10*num,另一个是10*num+1。这两个状态必然都是由0和1组成的。若将num 的初始状态设置为1,则可通过状态的扩展来覆盖整个查找空间中由0和1组成的数。由于从初始状态1开始不断扩展,扩展的数字必定比之前的数字大,扩展出来的状态不可能在此前出现过,因此不需要用数组来记录访问过的数字。
代码
Java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* Find The Multiple
* BFS:宽度优先搜索/广度优先搜索算法
*/
public class FindTheMultiple {
public static int BFS(int n){
Queue<Integer> queue = new LinkedList<>();
//初始化队列的值为1
queue.offer(1);
int m = 0;
while (!queue.isEmpty()){
int num = queue.poll();
if(num % n == 0){
m = num;
break;
}
queue.offer(num * 10);
queue.offer(num * 10 + 1);
}
return m;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int n = scanner.nextInt();
/*
判断程序是否结束; 若输入为0则结束
*/
if (n == 0) {
break;
}
System.out.println(BFS(n));
}
}
}
C++
/**
* Find The Multiple
* BFS: 宽度优先搜索/广度优先搜索
*/
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
int BFS(int n){
int m = 0;
//long long是一种整数类型,可以存储比普通int或long更长的整数值
queue<long long> intQueue;
intQueue.push(1);
while (!intQueue.empty()){
int num = intQueue.front();
intQueue.pop();
if(num % n == 0){
m = num;
break;
}
intQueue.push(num * 10);
intQueue.push(num * 10 + 1);
}
return m;
}
int main(){
int n = 0;
while (scanf("%d", &n) != EOF){
if(n == 0){
break;
}
printf("%d\n", BFS(n));
}
return 0;
}