题目传送门
思路:
- 初始化队列:从数字 1 开始,将其加入队列。
- 广度优先搜索:每次从队列中取出一个数字,检查它是否是 N 的倍数。如果是,则找到了最小的 M。如果不是,则将该数字乘以 10 和乘以 10 再加 1 的结果分别加入队列。
- 检查条件:在每次检查时,确保数字的十进制表示形式里只含有 1 和 0。"
代码&解释:
c++代码:
#include <iostream>
#include <string>
#include <queue>
using namespace std;
int N;
queue<long long> q;
bool isBinaryNumber(long long num) {
while (num > 0) {
if (num % 10 != 1 && num % 10 != 0) {
return false;
}
num /= 10;
}
return true;
}
int main() {
cin >> N;
q.push(1);
while (!q.empty()) {
long long current = q.front();
q.pop();
if (current % N == 0) {
cout << current / N << endl;
return 0;
}
long long next1 = current * 10 + 0;
long long next2 = current * 10 + 1;
q.push(next1);
q.push(next2);
}
cout << "No Solution" << endl;
return 0;
}
代码解释:
-
头文件和命名空间: 这些头文件和命名空间声明是必要的,用于输入输出、字符串处理和队列操作。
-
检查数字是否只包含1和0: 这个函数用于检查一个数字是否只包含1和0。它通过不断取数字的最后一位并检查是否为1或0,如果不是则返回false,否则继续检查直到数字为0。
-
主函数:
- 首先读取输入的正整数 。
- 初始化一个队列,并将数字1加入队列,因为我们要从最小的二进制形式数字开始搜索。
- 使用一个while循环进行广度优先搜索,直到队列为空。
- 在每次循环中,取出队列的第一个元素,检查它是否是 的倍数。如果是,则输出这个数字除以 的结果,并结束程序。
- 如果当前数字不是 的倍数,则生成两个新的数字(当前数字乘以10和当前数字乘以10再加1),并将它们加入队列,继续搜索。
- 如果队列为空且没有找到合适的 ,则输出 "No Solution"。
Python代码:
from collections import deque
def find_smallest_m(N):
if N == 1:
return 1
queue = deque([1])
visited = set([1])
while queue:
current = queue.popleft()
if current % N == 0:
return current // N
# 生成下一个可能的数字
next1 = current * 10
next2 = current * 10 + 1
if next1 not in visited:
queue.append(next1)
visited.add(next1)
if next2 not in visited:
queue.append(next2)
visited.add(next2)
return "No Solution"
# 读取输入
N = int(input())
# 输出结果
print(find_smallest_m(N))
代码解释:
- 初始化队列和集合:使用
deque
作为队列,set
作为已访问集合,避免重复计算。 - BFS 循环:从队列中取出当前数字,检查是否是 的倍数。如果是,返回当前数字除以 的结果。
- 生成下一个数字:将当前数字乘以 10 和乘以 10 再加 1,分别加入队列和已访问集合。
- 返回结果:如果找到满足条件的数字,返回该数字除以 的结果;否则返回 "No Solution"。
Pascal代码(先打的,仅供参考):
program P1988;
uses
SysUtils;
var
N: Integer;
Current: Int64;
PowerOf10: Int64;
begin
Readln(N);
if N = 1 then
begin
Writeln(1);
Exit;
end;
Current := 1;
PowerOf10 := 1;
while True do
begin
if Current mod N = 0 then
begin
Writeln(Current div N);
Exit;
end;
// 生成下一个只包含1和0的数字
Current := Current + PowerOf10;
PowerOf10 := PowerOf10 * 10;
// 检查是否超出范围
if PowerOf10 > High(Int64) div 10 then
begin
Writeln('No Solution');
Exit;
end;
end;
end.
代码解释:
头文件和命名空间
使用 SysUtils
库来处理输入输出。
变量声明
N
:输入的正整数。Current
:当前生成的只包含1和0的数字。PowerOf10
:用于生成下一个只包含1和0的数字的幂。
主程序
-
读取输入:
- 读取输入的正整数 。
-
特殊情况处理:
- 如果 为 1,直接输出 1 并结束程序。
-
初始化:
- 初始化
Current
为 1,PowerOf10
为 1。
- 初始化
-
循环生成数字:
- 使用一个 while 循环生成只包含1和0的数字,并检查它们是否是 的倍数。
- 如果找到一个数字是 的倍数,则输出这个数字除以 的结果,并结束程序。
- 生成下一个只包含1和0的数字:将
Current
加上PowerOf10
,然后将PowerOf10
乘以 10。 - 检查是否超出
Int64
的范围:如果PowerOf10
大于Int64
的最大值除以 10,则输出 "No Solution" 并结束程序。