Python题解—带分数
带分数
题目描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0 )。
类似这样的带分数,100 有 11 种表示法。
输入描述
从标准输入读入一个正整数 N (N<1000×1000)。
输出描述
程序输出该数字用数码 1∼9 不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
样例输入
100
样例输出
11
问题分析:
- 首先的思路肯定是把所有可能的带分数遍历出来,然后一一比较。先对所有排列遍历,再对+位置遍历,在对/位置遍历。但发现tle了。
- 首要目的肯定还是要减少循环。在这种乘除运算中,有一个特殊之处,即末尾数字的运算是与其他数字运算是没关系的。所以我们只要确定了+位置,即可算得b的末尾数字。又由于这里的数字是唯一的,所以我们我们就能确定出b。这样我们就通过数学的手段减少了一个循环。
拟定计划:
- 数字的拼接要用到字符串,数字的大小计算又要用到整型
- 一个排列要分成三段a,b,c。a + b // c
- 两层循环,一层循环算排列,另一层循环确定分段。
- 算出数然后比较。
from itertools import*
n = int(input())
lenth = len(str(n))
count = 0
number = [f'{i}' for i in range(1, 10)]
for element in permutations(number):
for i in range(lenth):
# 将加法前面的部分a提取出来
a = int(''.join(element[ : i + 1]))
# 后面一部分的值d
d = n - a
# 通过对b末尾数的计算可以把b提取出来
bl_num = d * int(element[-1]) % 10
# 如果该数为0,则不行
if bl_num == 0 :
continue
# 在数字中找到b末尾数的位置,从而可以完全确定b
bl_poi = element.index(str(bl_num))
# 如果该位置在a,或为最后一个数,则不行
if bl_poi <= i or bl_poi == 8 :
continue
b = int(''.join(element[i + 1 : bl_poi + 1]))
c = int(''.join(element[bl_poi + 1 : ]))
if a + b // c == n and b % c == 0:
count += 1
print(count)
回顾反思:
- 写代码时,一定要小心字符串和数字。本题因为要对数字进行拼接,所以肯定是要用到字符串的。
- 写代码时,一定要考虑边界情况,每一步都要小心。女人和小孩 能够粗心大意,但男人不行!我花了一辈子,只学会了小心!——《教父》
- 三重循环往往很难通过,我们有时必须通过数学的方法来减少循环。
- 在遇到这种乘除的题目时,通过末尾的计算来简化程序,是一个非常重要的技巧。
- 除法会产生浮点数,所以尽量使用整除。