Python题解—带分数

带分数

题目描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714

还可以表示为:100 = 82 + 3546 / 197

注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0 )。

类似这样的带分数,100 有 11 种表示法。

输入描述

从标准输入读入一个正整数 N (N<1000×1000)。

输出描述

程序输出该数字用数码 1∼9 不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!

样例输入
100
样例输出
11

问题分析:

  1. 首先的思路肯定是把所有可能的带分数遍历出来,然后一一比较。先对所有排列遍历,再对+位置遍历,在对/位置遍历。但发现tle了。
  2. 首要目的肯定还是要减少循环。在这种乘除运算中,有一个特殊之处,即末尾数字的运算是与其他数字运算是没关系的。所以我们只要确定了+位置,即可算得b的末尾数字。又由于这里的数字是唯一的,所以我们我们就能确定出b。这样我们就通过数学的手段减少了一个循环。

拟定计划:

  1. 数字的拼接要用到字符串,数字的大小计算又要用到整型
  2. 一个排列要分成三段a,b,c。a + b // c
  3. 两层循环,一层循环算排列,另一层循环确定分段。
  4. 算出数然后比较。
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)

回顾反思:

  1. 写代码时,一定要小心字符串和数字。本题因为要对数字进行拼接,所以肯定是要用到字符串的。
  2. 写代码时,一定要考虑边界情况,每一步都要小心。女人和小孩 能够粗心大意,但男人不行!我花了一辈子,只学会了小心!——《教父》
  3. 三重循环往往很难通过,我们有时必须通过数学的方法来减少循环。
  4. 在遇到这种乘除的题目时,通过末尾的计算来简化程序,是一个非常重要的技巧。
  5. 除法会产生浮点数,所以尽量使用整除。
posted @ 2022-01-29 15:33  潮自生  阅读(207)  评论(0)    收藏  举报