P1988 火炬

题目传送门

思路:

  1. 初始化队列:从数字 1 开始,将其加入队列。
  2. 广度优先搜索:每次从队列中取出一个数字,检查它是否是 N 的倍数。如果是,则找到了最小的 M。如果不是,则将该数字乘以 10 和乘以 10 再加 1 的结果分别加入队列。
  3. 检查条件:在每次检查时,确保数字的十进制表示形式里只含有 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. 头文件和命名空间: 这些头文件和命名空间声明是必要的,用于输入输出、字符串处理和队列操作。

  2. 检查数字是否只包含1和0: 这个函数用于检查一个数字是否只包含1和0。它通过不断取数字的最后一位并检查是否为1或0,如果不是则返回false,否则继续检查直到数字为0。

  3. 主函数

    • 首先读取输入的正整数 。
    • 初始化一个队列,并将数字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))

代码解释:

  1. 初始化队列和集合:使用 deque 作为队列,set 作为已访问集合,避免重复计算。
  2. BFS 循环:从队列中取出当前数字,检查是否是  的倍数。如果是,返回当前数字除以  的结果。
  3. 生成下一个数字:将当前数字乘以 10 和乘以 10 再加 1,分别加入队列和已访问集合。
  4. 返回结果:如果找到满足条件的数字,返回该数字除以  的结果;否则返回 "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. 读取输入

    • 读取输入的正整数 。
  2. 特殊情况处理

    • 如果  为 1,直接输出 1 并结束程序。
  3. 初始化

    • 初始化 Current 为 1,PowerOf10 为 1。
  4. 循环生成数字

    • 使用一个 while 循环生成只包含1和0的数字,并检查它们是否是  的倍数。
    • 如果找到一个数字是  的倍数,则输出这个数字除以  的结果,并结束程序。
    • 生成下一个只包含1和0的数字:将 Current 加上 PowerOf10,然后将 PowerOf10 乘以 10。
    • 检查是否超出 Int64 的范围:如果 PowerOf10 大于 Int64 的最大值除以 10,则输出 "No Solution" 并结束程序。

希望这些代码能帮助您理解并解决这个问题,如果有问题,请随时提问。
  蒟蒻题解,神犇勿喷,点个赞再走吧!QAQ
  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值