Python【填空题】手算技巧

目录

什么是手算题?

手算技巧

01、巧用编辑器

例题1:门牌制作

例题二:卡片 

02、心算手数

例题三:迷宫 

例题四:七段码

03、巧用Excel

例题五:分数

例题六:星期一

 04、巧用Python

 例题六:顺子日期 

用Python处理大数

例题七:乘积尾零  

用Python处理字符

例题八:平方和 

例题九:三角回文数


什么是手算题?

应用场合:填空题

手算的目的:减少做题时间,省下时间做编程题。

手段:

  • 不编码,或者只做部分编码
  • 用推理获得答案
  • 用软件工具帮助计算

手算技巧

01、巧用编辑器

例题1:门牌制作

门牌制作   2020年第十一届蓝桥杯省赛,填空题
【问题描述】从1到2020的所有数字中,共有多少个2?

思路一:借助编辑器
先编码连续打印出1 ~2020这2020个数字(或者用Excel输出1~2020),然后粘贴到任何一个编辑器中(Word或者Excel),选查询替换功能,查找或替换字符“2”,共624次,就是答案。

s = " "
for i in range (1,2021):
    s += str(i)
print(s)
'''
for i in range(1,2021):    # 每次都要打印,非常慢(不推荐)
    print(i ,end = '')
'''

或者 

替换/查找 :

思路二:编码

s=' '
for i in range( 1,2021):
    s+=str(i)
print(s.count( '2')) # 624

例题二:卡片 

卡片   2021第十二届蓝桥杯省赛,填空题,lanqiaoOJ题号I443
【问题描述】小蓝有很多数字卡片,每张卡片上都是数字0到9。小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。小蓝想知道自己能从1拼到多少。例如,当小蓝有30张卡片,其中0到9各3张,则小蓝可以拼出1到10,但是拼11时卡片1已经只有一张了,不够拼出11。现在小蓝手里有0到9的卡片各2021张,共20210张,请问小蓝可以从1拼到多少?

【题意分析】
例如有30张卡片,其中0到9各3张,则小蓝可以拼出I到10,但是拼11时卡片1已经只有一张了,不够拼出11。
卡片:000 111 222 333 444 555 666 777 888 999
拼数:1 2 3 4 5 6 7 8 9 10 11
【思路】

  • 倒过来想,先假设能从1拼到X,然后看1~X需要的数字,哪个数字用得最多。检查这个数字用的次数。
  • 先估计可能拼出3000多个数。编码打印或者用Excel输出1~3500,然后全部贴到编辑器里,检查1用了多少次(搜索有多少个1)、2用了多少次、……最后发现1用的最多,然后每次都检查多少个1,逐渐往2021个1靠近,最后就能得到答案。所以答案是3181。
# 编码打印1~3500:
s=''
for i in range( 1,3501):
    s=s+str( i)+''
print(s)

# 不要这样写,因为Python的打印太慢了
# for i in range(1,3501):
#     print(i,end=' ')

02、心算手数

例题三:迷宫 

迷宫2017年第八届蓝桥杯省赛,填空题,lanqiaoOJ题号641

【问题描述】

X 星球的居民有点懒,不愿意费力思考。他们更喜欢玩运气类的游戏。这个游戏也是如此!

开始的时候,直升机把 100 名玩家放入一个个小房间内。玩家一定要按照地上的字母移动。

迷宫地图如下:

UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR

请你计算一下,最后,有多少玩家会走出迷宫,而不是在里边兜圈子? 

如果你还没明白游戏规则,可以参看下面一个简化的 4x4 迷宫的解说图:

【分析】

   有的填空题本身比较复杂,但是因为数据规模小,用不着编码,能直接通过眼睛看、动手数得到答案。 因为是个填空题,而且迷宫很简单,只有100个字符,可以直接数,约2分钟就能数完。

【 思路】

第一行U可以走出迷宫,倒数第一行D可以走出迷宫;第一列L可以走出迷宫,倒数第一列R可以走出迷宫。中间的左右相邻的R和L可以抵消,中间的上下相邻的U和D也可以抵消。

正解:DFS搜索

例题四:七段码

七段码2020年第十一届蓝桥杯省赛,填空题,lanqiao0J题号595

【问题描述】
七段数码管,一共有7个发光二极管,问能表示多少种不同的字符,要求发光的二极管是相连的。

因为图形简单,直接手算也行,约3~5分钟。
【思路】:用字符表示数码管不太方便,改用数字: a ~ g分别用1~7表示。统计这些组合中的连续亮灯,分7种情况统计:

  • 亮一个灯:1、2、3、4、5、6、7,共7种
  • 亮两个灯:12、13、24、25、34、36、45、46、57、67,共10种
  • 亮三个灯:123、124、125、134、136、234、245、246、257、345、346、367、456、457、467、567,共16种
  • 亮四个灯,这时不要直接数四个灯,情况与灭三个灯是等价的,数三个灯比数四个灯简单。注意灭三个灯后其他的四个亮灯是连续的:123、124、125、126、127、134、135、136、137、157、167、245、257、267、346、357、367、457、467、567,共20种
  • 亮五个灯:数灭两个灯的情况:12、灭13、灭14、...等,共19种
  • 亮六个灯:数灭一个灯的情况,有7种
  • 亮七个灯:有1种。
  • 对以上所有情况求和,答案是80。

 正解:DFS+并查集

03、巧用Excel

 Excel的编辑、统计、计算功能很强大。
如果题目能手算,且需要比较多的编辑、统计、计算,可以利用Excel。

分数2018年第九届蓝桥杯,填空题,lanqiao0J题号610

例题五:分数

分数2018年第九届蓝桥杯,填空题,lanqiao0J题号610

【问题描述】
1/1+ 1/2+ 1/4 + 1/8 + 1/16 +…每项是前一项的一半,如果一共有20项,求这个和是多少,结果用分数表示出来(类似:3/2​,当然,这只是加了前 2 项而已)。分子分母要求互质

【思路】

  • 在Excel表格的A列填分子,都是1;B列填分母,每行递增2倍,做法是在B1填1,在B2填写“=B1*2”,然后按住B2往下拉到第20行,就填好了所有的分母。
  • 最后通分求分子分母。分母就是B20的524288,分子实际上就是“SUM(B1:B20)”,用鼠标选中这个区域,Excel自动算出1048575。

下面用Excel演示计算过程:

例题六:星期一

 星期一2018年第九届蓝桥杯省赛,填空题,lanqiao0J题号611

【问题描述】

整个20世纪(1901年1月1日至2000年12月31日之间),一共有多少个星期一?

【思路】
        用Excel,在一个格子里输入日期1901年1月1日,另一个格子输入2000年12月31日,然后两个格子相减得36524天,除以7得5217.7周。0.7周可能包括一个星期一,继续讨论。

        再看1901年1月1日是星期几。用Excel点1901年1月1日这一格的右键“设置单元格式-数字-日期-星期三”,点击“确定”,得“星期二”,即1901年1月1日是星期二,36524是5217周多5天(0.7周),最后5天没有星期一,说明答案就是5217。也直接利用Excel“单元格格式”对话框得出2000年12月31日刚好是星期天,从星期二至星期天之间没有星期一。

 04、巧用Python

填空题遇到字符、大数字、日期问题,Python是首选。(做部分推理计算)

这里用python来求解上面例题:星期一

【问题描述】

整个20世纪(1901年1月1日至2000年12月31日之间),一共有多少个星期一?

【思路】

直接用datetime库求解,这是推荐用法。日期.weekday()可以输出某个日期是星期几。

from datetime import *
dt1 = datetime(1901,1,1)
dt2 = datetime(2000,12,31)
td = dt2- dt1
print(td.days/7)    # 5217.7   0.7周可存在一个星期一

# 验证 0.7周(5天)是否存在一个星期一
print(dt1.weekday())#dt1的星期  注意:周一是O,周日是6
# 输出1表示周二,再过五天也没有星期一,所以0.7周(5天)不存在一个星期一。
print( td.days//7)  # 5217

 例题六:顺子日期 

顺子日期2022年第十三届蓝桥杯省赛,填空题lanqiao0J题号2096

        小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022 年份中,一共有多少个顺子日期?

【思路】

 时间问题用Python非常方便。把日期转为字符,然后判断顺子。

from datetime import *
dt1 = datetime(2022,1,1)
cnt = 0
for i in range(0,366):
    s="%02d%02d%02d"%(dt1.year,dt1.month,dt1.day)   #转换成字符串(输出两个字符,若不足两个在前面补零.若满足≥两个字符则输出原字符)
    dt1 += timedelta(days=1)            #timedelta有三种: days,seconds,microseconds
    if "012" in s or "123" in s:        # 只可能是这两种情况
        cnt +=1
print(cnt)          #  14

用Python处理大数

  • 遇到大数,用Python处理最简单,可以直接硬算
  • 不像C/C++代码那样要考虑数据类型和溢出问题

例题七:乘积尾零  

乘积尾零  2018年第九届蓝桥杯省赛,填空题,lanqiao0J题号612
【问题描述】

如下的 10 行数据,每行有 10 个整数,请你求出它们的乘积的末尾有多少个零?

5650 4542 3554 473 946 4114 3871 9073 90 4329 
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899 
1486 5722 3135 1170 4014 5510 5120 729 2880 9019 
2049 698 4582 4346 4427 646 9742 7340 1230 7683 
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649 
6701 6645 1671 5978 2704 9926 295 3125 3878 6785 
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915 
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074 
689 5510 8243 6114 337 4096 8199 7313 3685 211 
data = "5650 4542 3554 473 946 4114 3871 9073 90 4329 \
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 \
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899 \
1486 5722 3135 1170 4014 5510 5120 729 2880 9019 \
2049 698 4582 4346 4427 646 9742 7340 1230 7683 \
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649 \
6701 6645 1671 5978 2704 9926 295 3125 3878 6785 \
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915 \
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074 \
689 5510 8243 6114 337 4096 8199 7313 3685 211"
num = data.split()  # 返回一个列表
s = 1
for i in num :
    s=s*int(i)              # 直接连乘,结果是一个极大的数
cnt =0
while s%10 == 0:            # 取余:逐个统计末尾的零的个数(末尾不是零则退出)
    s //=10                 # 除以10,把末尾的零去掉
    cnt +=1                 # 统计0的数量
print(cnt)                  # 31

用Python处理字符

例题八:平方和 

平方和2019年第十届蓝桥杯省赛,填空题,lanqiao0J题号599
【问题描述】

小明对数位中含有 2、0、1、9 的数字很感兴趣,在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574,平方和是 14362。

注意,平方和是指将每个数分别平方后求和。

请问,在 1 到 2019 中,所有这样的数的平方和是多少?

sum = 0
for i in range( 1,2020):
    s = str(i)
    if '2' in s or '0' in s or '1' in s or '9'in s:
        sum+= i*i
print( sum)

例题九:三角回文数

2022年第十三届省赛,填空题
【问题描述】
        对于正整数n,如果存在正整数k使得n = 1 + 2 + 3 +…+ k = k(k+1)/2,则n称为三角数。例如,66066是一个三角数,因为66066 = 1 + 2+ 3 +…+ 363。如果一个整数从左到右读出所有数位上的数字,与从右到左读出所有数位上的数字是一样的,则称这个数为回文数。例如,66066是一个回文数,8778也是一个回文数。如果一个整数n既是三角数又是回文数,我们称它为三角回文数。例如66066是三角回文数。请问,第一个大于20220514的三角回文数是多少?

【 思路】

  • 本题遍历k,而不是遍历n。20220514对应的k大于6000,让k从6000开始。第3行把n转为字符串s;反串在Python中的表示非常简单,s的反串是第4行的s[::-1]。
  • 先找三角数,再判断回文数
for k in range( 6000,20000):
    n= k*(k+1)//2
    s = str(n)
    if s[::-1] == s:
        print(k) # 8382
        break

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小叶pyか

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值