Skip to content

01426: Find The Multiple

http://cs101.openjudge.cn/practice/01426/

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.

输入

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.

输出

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.

样例输入

2
6
19
0

样例输出

10
100100100100100100
111111111111111111

来源

Dhaka 2002

考虑到我们的结果至多是100位数,我们需要找到一个能被n整除的数字,并且全是0、1,实际上所有位上都是0、1的数字是可以构成一颗二叉树的,我们从1作为根节点,左右儿子分别进行*10和*10+1操作——并且我们不关心数字实际的大小,而关心这个数mod n的结果,由于mod运算的结合、分配律,所以我们可以进行vis去重,这大大降低了搜索的成本,于是我们直接用bfs就可以了(虽然题目不要求最短这个性质,但即便如此相比之下bfs也比dfs更高效)

对余数进行BFS(广度优先搜索)。思路是从最小的满足条件的数开始搜索,即1,然后通过不断添加0或1在数的末尾来生成新的数字,直到找到一个数字既是n的倍数又只包含数字0和1。

由于直接操作数字可能会很快超出整数范围,特别是当n很大时,我们可以在BFS过程中仅保存数字的模n值以及该数字的十进制表示。每次从队列中取出一个元素,计算加0或加1后的模n值,如果新模n值为0,则找到了解;否则,如果这个模n值是首次访问,则将其加入队列继续搜索。

下面是Python代码实现:

python
from collections import deque

def find_multiple(n):
    # 使用队列实现BFS
    q = deque()
    # 初始化队列,存储的是(模n值, 对应的数字字符串)
    q.append((1 % n, "1"))
    visited = set([1 % n])  # 用于记录访问过的模n值,避免重复搜索

    while q:
        mod, num_str = q.popleft()

        # 检查当前模n值是否为0,是则找到答案
        if mod == 0:
            return num_str

        # 尝试在当前数字后加0或加1,生成新的数字,并计算模n值
        for digit in ["0", "1"]:
            new_num_str = num_str + digit
            new_mod = (mod * 10 + int(digit)) % n

            # 如果新模n值未访问过,则加入队列继续搜索
            if new_mod not in visited:
                q.append((new_mod, new_num_str))
                visited.add(new_mod)

def main():
    while True:
        n = int(input())
        if n == 0:
            break
        print(find_multiple(n))

if __name__ == "__main__":
    main()

这段代码首先读取输入的n值,然后调用find_multiple函数来找到满足条件的最小的由0和1组成的n的倍数。find_multiple函数通过广度优先搜索实现,搜索过程中仅记录和处理模n值,这样可以有效避免处理过大的数字。当找到一个模n值为0的数字时,即找到了一个满足条件的倍数,函数返回该数字的字符串表示。

先把输入变成奇数,除掉的2的数量,在最后用'0'补全,然后用bfs从0开始逐位添加0或者1,查找可以整除的数

python
# 钟明衡 物理学院
def bfs(n):
    l = [0]
    s, e = 0, 1
    while s != e:
        for i in range(s, e):
            for j in (0, 1):
                x = l[i]*10+j
                if x:
                    if x % n:
                        l.append(x)
                    else:
                        return str(x)
        s, e = e, len(l)
    return ''


while (n := int(input())):
    c = 0
    while (n+1) % 2:
        n //= 2
        c += 1
    print(bfs(n)+'0'*c)

思路:比较偏bfs的想法。从位数小起步,如果找不到的话,在后面加0或者1。一个简化算法的方式是,如果有mod相同的可以剔掉

python
#2200015507 王一粟
from collections import deque
def find(n):
    if n == 1:
        return 1
    queue = deque([10,11])
    mylist = [1]
    while queue:
        element = queue.popleft()
        t = element % n
        if t == 0:
            return str(element)
        else:
            if t not in mylist:
                mylist.append(t)
                queue.append(element*10+1)
                queue.append(element*10)
while True:
    n = int(input())
    if n == 0:
        break
    else:
        print(find(n))