大数守形数计算

博客围绕守形数展开,介绍其定义,即n位数x满足x^2 % (10^n) = x。指出常规枚举法无法计算大数守形数,证明了守形数的低位一定是守形数这一定理,并以二位数扩展得到100位守形数,将n位数守形数计算复杂度从O(10^n)降至O(n)。

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

最近做到一题数学题

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from secret import flag

assert flag[:6] == "flag{b"
assert flag[-1] == "}"
t = int(flag[5:-1], 16)
assert t > 10**99
assert t < 10**100
assert pow(t, 2, 10**100) == t

一个数字,他的平方取模后得到自己。

这个是标准的守形数,或者称为自守数、自构数。

网上找了一圈守形数的计算方法,都是用枚举,计算量小的时候还可以,这题数字大到100位,根本没办法枚举计算。

守形数定义

一个n位数x,满足
x^2 % (10^n) = x,即为守形数

尝试数学分析:

守形数定理

守形数的低位一定是守形数

证明如下

假设一个守形数xy,他的低位是y,即假设x为第n位数

守形数为 x*10^n + y

满足 (x*10^n + y) ^ 2 % (10^n) = x * 10^n + y

即 (x * 10^2n + 2* x * y * 10 ^ n + y ^2) % (10^n) = y ^2

y ^2 = x * 10 ^ n + y

y满足守形数的定义,所以得证,守形数的低位必是守形数。

计算大数守形

我们知道,一位数的守形数有1、5、6,二位数的有 25、76,我们以2位数进行扩展

得到100位的守形数为:

6046992680891830197061490109937833490419136188999442576576769103890995893380022607743740081787109376

3953007319108169802938509890062166509580863811000557423423230896109004106619977392256259918212890625

其中
6046992680891830197061490109937833490419136188999442576576769103890995893380022607743740081787109376
满足16进制首位为b,得到结果。

kk = ['5','6']
j=1
while(1):
    lenkk = j
    for c in kk:
        if len(c) == lenkk:
            for i in range(10):
                b = str(i) + c
                slend = pow(10,len(b))
                if pow(int(b),2,slend) == int(b):
                    kk.append(b)
                    if len(b) == 100:
                        print(b)
    j=j+1
    if j == 100:
        break

得到结果

3953007319108169802938509890062166509580863811000557423423230896109004106619977392256259918212890625
6046992680891830197061490109937833490419136188999442576576769103890995893380022607743740081787109376

n位数的守形数计算复杂度由O(10^n)降低到O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值