鱼C论坛

 找回密码
 立即注册
查看: 6466|回复: 18

[技术交流] 15 - 数之吟唱:自守数

[复制链接]
发表于 2021-7-19 17:46:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2021-8-19 19:14 编辑

在线视频:




                               
登录/注册后可看大图


这一讲我们来看“自守”数,注意哈,不是自首~

自守数是什么呢?

这种数是指一个数的平方的尾数等于该数自身的自然数

例如:

52=25
252=625
762=5776

接下来我们通过编程找出求 100000 以内的自守数。

根据要求,关键就是知道当前所求自然数的位数,以及该数平方的尾数与被乘数、乘数之间的关系。

一讲一讲学到现在,我们第一时间想到的应该是在13 - 数之吟唱:回文中那样拆分。

先求平方,然后按照原数长度就“切”平方后的结果。

既然如此,我们先动手实现求给定数的位数。

我们可以借助最高位的权值来计算。

对于十进制来说,个位的权值为 100,十位的权值为 101,百位的权值为 102,以此类推。

一个存储三位数的变量 n=233,每次地板除 10,将得到的值再赋给 n,直到 n 的值为 0,最多可以除 3 次;

若变量 n 中存储的是 4 位数,用同样的方法去地板除 10 最多可以除 4 次。

相信应该有童鞋已经发现当变量变为 0,地板除 10 的次数即为当前给定数的位数。

先将上面的过程写成代码:

  1. print("输入任意一个正整数:",end="")
  2. n = int(input())
  3. if n<= 0:
  4.     print("不可以这么输入哦!")
  5.     exit()
  6. count = 0
  7. while n != 0:
  8.     n //= 10
  9.     count += 1
  10. print("位数为",count)
复制代码

运行一下:

2021-07-20_18-57-16.jpg

里面加了防止用户输入错误数字的判断,以后代码有需要,直接拿来用就好。

知道了怎么求位数,那么按照正常逻辑,就是将平方后的数拆分了对吧。

按照位数分离给定数的最后几位

先从一个两位数开始分析,分离最低位个位:

  1. n%10
复制代码

对于三位数,分离最后两位:

  1. n%100
复制代码

对于四位数,分离最后三位:

  1. n%1000
复制代码

以此类推,发现规律了吧,若分离出最后 x 位,只需要用原数对 10x 求余就好。

因为现在是循环 0 到 100000 之间的数,初始值位数最多不过从 1 到 5 位。

按照位数依次取余就好,这个“笨笨”的方法,留给你们当课后作业了!

这里其实还有更简单的做法,根本不用找出位数,反正最多 5 位,那就直接利用 if..elif % 10n 就能搞定!

代码:
游客,如果您要查看本帖隐藏内容请回复

结果:

2021-08-13_20-21-51.jpg

这种方法肯定比刚才说的第一种,先统计位数,再去 % 判断来的简单~

源码: py15.py.zip (687 Bytes, 下载次数: 7, 售价: 6 鱼币)

其实除了上面这种判断位数操作,还可以将数字转为字符串判断长度:

  1. count=len(str(n))
复制代码

快速找到几位数,然后求解,算是精简第一种方法:

  1. for n in range(1,10000):
  2.     # 求数的长度
  3.     k=len(str(n))
  4.     # 计算数的后几位
  5.     t=(n*n) % (10**k)
  6.     if t==n:
  7.         print(n)
复制代码

当你水平更高的时候,甚至可以使用列表解析式一行代码搞定:

  1. print([n for n in range(1,10000) if (n*n) % (10**len(str(n)))==n])
复制代码


这就是算法设计的魅力,不同段位的人写出不一样的代码~

这节课信息量有点大,留给童鞋们自己去好好消化,下课!

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
睦ちゃん她爹 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-19 18:53:48 | 显示全部楼层
本帖最后由 qiuyouzhi 于 2021-7-20 10:38 编辑

沙发
  1. for i in range(99999):
  2.     if i == i ** 2 % (10 ** len(str(i))):
  3.         print(f"{i} ** {i} == {i ** 2}")
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-7-19 20:35:16 | 显示全部楼层


不错不错,0和1也算噢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-19 21:25:05 | 显示全部楼层
  1. for i in range(999999):
  2.     i_1 = str(i**2)
  3.     if str(i) == i_1[-len(str(i)):]:
  4.         print(i,i_1)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-20 10:38:28 | 显示全部楼层
鱼C-小师妹 发表于 2021-7-19 20:35
不错不错,0和1也算噢

噢,忘了,感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-20 11:45:32 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-20 09:44:18 | 显示全部楼层
视频更新啦!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-10-10 14:22:47 | 显示全部楼层
代码:
  1. [print(n) for n in range(100000) if bool(int(str(n*n)[len(str(n*n))-(len(str(n))):]) == n)]
复制代码
输出:
  1. 0
  2. 1
  3. 5
  4. 6
  5. 25
  6. 76
  7. 376
  8. 625
  9. 9376
  10. 90625
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-5 16:26:55 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-8 21:23:03 | 显示全部楼层
我太笨了!把我自己都写晕了。
  1. n = 0
  2. count = 0
  3. while n <= 100000:
  4.     m = n*n
  5.     if n < 10:
  6.         if m < 10:
  7.             if m == n:
  8.                 print(f'{n}是自守数')
  9.                 count += 1
  10.         else:
  11.             if (m%10) == n:
  12.                 print(f'{n}是自守数')
  13.                 count += 1

  14.     elif n < 100:
  15.         if (m%100) == n:
  16.             print(f'{n}是自守数')
  17.             count += 1

  18.     elif n < 1000:
  19.         if (m%1000) == n:
  20.             print(f'{n}是自守数')
  21.             count += 1

  22.     elif n < 10000:
  23.         if (m%10000) == n:
  24.             print(f'{n}是自守数')
  25.             count += 1
  26.         
  27.     else:
  28.         if (m%100000) == n:
  29.             print(f'{n}是自守数')
  30.             count += 1

  31.     n += 1
  32. print(f'100000以内共有{count}个自守数')
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-30 11:08:31 | 显示全部楼层
瞧瞧代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-17 02:55:14 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-8 23:09:01 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-5-9 11:02:07 | 显示全部楼层
# 题干
# 自守数是指一个数的平方的尾数等于该数自身的自然数
# 5^2=25 25^2=625 76^2=5776
# 找出求 100000 以内的自守数

count = 0
for n in range(100001):
    length = len(str(n))
    N = n * n
    N_mod = str(N)[-length:]
    if N_mod == str(n):
        print('%d是自守数:%d^2 = %d' % (n, n, N))
        count += 1
        continue
    else:
        pass
print('0 - 100000 中共有%d个自守数' % count)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-25 18:22:05 | 显示全部楼层
print("100000以内的自守数:")
for i in range(100000):
    count = len(str(i))
    if i == i * i % (10 ** count):
        print(i, "是自守数")
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-25 18:34:36 | 显示全部楼层
不判断位数的话,循环去除是不是更简单些
for i in range(0, 100000):
    num = i * i
    for j in range(1, 6):
        if num % (10 ** j) == i:
            print('{}是自守数'.format(i))
            break
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-14 16:33:47 | 显示全部楼层
#第一种
for i in range(100000):
    num = i*i
    k = len(str(i))
    if i == num%(10**k):
        print(i)

#第二种
print([i for i in range(10000) if (i*i) % (10**len(str(i))) == i ])
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-5 21:48:01 | 显示全部楼层
沙发
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-2 09:18:10 | 显示全部楼层
学习一下下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 19:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表