【简单搜索】Find The Multiple

本文介绍了FindTheMultiple问题的两种解法:dfs和bfs。通过对比两种方法的实现,详细解释了如何找到给定整数n的一个倍数m,使得m仅由0和1组成,且不超过100位。同时,文中还分享了在使用bfs方法时遇到的错误及解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Find The Multiple

题目描述

Given a positive integer n, write a program to find out a nonzero
multiple m of n whose decimal representation contains only the digits
0 and 1. You may assume that n is not greater than 200 and there is a
corresponding m containing no more than 100 decimal digits.

Input

The input file may contain multiple test cases. Each line contains a
value of n (1 <= n <= 200). A line containing a zero terminates the
input.

Output

For each value of n in the input print a line containing the
corresponding value of m. The decimal representation of m must not
contain more than 100 digits. If there are multiple solutions for a
given value of n, any one of them is acceptable.

Sample Input

2
6
19
0

Sample Output

10
100100100100100100
111111111111111111

这题比较简单,有两种解法:dfs和bfs。
dfs使用了递归,也就是系统的栈,去检索符合的答案;bfs使用了队列。
个人推荐使用bfs。

bfs

//E-Find The Multiple
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long int bigint;
int n;
void bfs(){
	queue<bigint> Q;
	Q.push(1);
	while(Q.size()){
		bigint temp=Q.front();
		Q.pop();
		if(temp%n==0){
			printf("%lld\n", temp);
			return;
		}
		Q.push(temp*10);
		Q.push(temp*10+1); 
	}
}
int main(void){
	while(~scanf("%d", &n), n){
		bfs();
	}
	return 0;
}

dfs

//E-Find The Multiple
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long int bigint;
int n;
bool flag=false;
void dfs(int bit, bigint num){
	if(bit>19 || flag){
		return;
	}
	if(num%n==0){
		flag=true;
		printf("%lld\n", num);
		return;
	}
	dfs(bit+1, num*10);
	dfs(bit+1, num*10+1);
} 
int main(void){
	while(~scanf("%d", &n), n){
		flag=false;
		dfs(1, 1);
	}
	return 0;
}

犯过的错误

在使用bfs时,并不推荐以下代码:

#define MAXN 10005
void bfs(){
	int head, tail;
	head=tail=0;
	bigint Q[MAXN];
	Q[tail]=1;
	tail++;
	while(tail>head){
		printf("%d\n", n);
		bigint temp=Q[head];
		head++;
		if(temp%n==0){
			printf("%lld\n", temp);
			return;
		}
		Q[tail]=temp*10;
		tail++;
		Q[tail]=temp*10+1;
		tail++;
	}
}
int main(void){
	while(~scanf("%d", &n), n){
		bfs();
	}
	return 0;
}

在某些情况下自己用数组写一个队列能够提高效率。但这必须是在队列中的元素比较有限,不能多于数组所能容纳的最大数量。而当数组的容量相当大时,遍历的时间又很长了,得不偿失。
引用dalao原话:

这个和栈大小有关系,与编译器、系统都有关系。你定义成全局变量 1000000也是可以的,并不是越大越慢。
上面说的数组大小越大,从指针首地址移动至末尾的时间当然也就越长是对的 。当然这指的运行的时候的操作。当内存分配的时候,操作用的时间是一样。就是指定一个标识起始位置的指针,和一个数组的大小。再大也就这两个值。当然运行起来,大数组遍历一般时间更长~

而stl中的queue容器所能push的最大元素数量,在网上有两种说法:

  • 与内存大小有关
  • queue默认采用的是deque作为底层的容器,deque最大的容量是
    size_type max_size() const { return size_type(-1); }
    而且又定义
    typedef size_t size_type;
    所以只跟系统内部定义的size_t有关。

但这都说明了,stl中的queue容器是非常大的,至少比数组大。
在这题里,上述代码在submit时,出现了运行时错误。而在我自己做输出调试时,输入样例“99”,发现入队元素数量直接突破了数组边界,尽管数组已经调试到最大容量。

总结

在入队元素数量不能确定时,还是用stl的queue吧。
这也给我一点启发:
在做递归的非递归化时,也应该清楚进层的层数。

  • 1605集训计划第5天任务
  • 延期1天完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值