打表法和模拟法——按照意思去模拟

算式问题

题目描述:

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

看这个算式:

☆☆☆ + ☆☆☆ = ☆☆☆

如果每个五角星代表 1 ~ 9 的不同的数字。这个算式有多少种可能的正确填写方法?

173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675

以上都是正确的填写法!

注意:111+222=333 是错误的填写法!因为每个数字必须是不同的!也就是说:1 ~ 9 中的所有数字,每个必须出现且仅出现一次!

注意:不包括数字 “0”。

注意:满足加法交换率的式子算两种不同的答案。 所以答案肯定是个偶数!

运行限制:

  1. 最大运行时间:1s
  2. 最大运行内存: 128M

题目分析

首先我们能了解到这道题只需要答案,那么对于时间要求就等于无限,那我们可以使用模拟方法,因为只需要输出答案即可,只要能够在比赛的时长里跑出来即可。

接下来我们将采用模拟法进行问题的求解,注意既然我们不需要考虑时间问题和代码问题,我们一定要将代码设计的具有较高的逻辑性和准确性。

这个题的正解是搜索算法,但是既然只要答案我们求快、求简单,在这里我们使用另一种方式进行解答。

这里有三个数字 我们称 A + B = C 且各个位上的数字不同。
我们这里借助桶排序的思想来判断 1-9 这些数字有没有占用。
所以我们定义一个判断函数,用于判断 A B C 三个数字是否符合要求。

然后暴力枚举:

A 从 123 到 987 开始枚举
有很多同学开始抬杠 111-999 岂不是更简单,因为 123 是最小的符合要求的数字,可以减少枚举的次数,987 是最大的符合要求的数字。

B 从 123 到 987-A 枚举
这时候又会有很多同学来问,为什么不直接枚举与 A 不一样的数字呢,那么又得考虑每一位的问题,这样的模拟已经不是暴力法了,我们要做的就是在不改变完成难度的情况下,减少复杂度。所以要分清注次。

C = A + B 这时候只要检查 A B C 是否符合要求即可。

代码

def check(a, b, c):
  flag = []
  flag.append(0)

  while (a != 0):

      if (a % 10 in flag):
          return False;
      else:
          flag.append(a % 10)

      if (b % 10 in flag):
          return False;
      else:
          flag.append(b % 10)

      if (c % 10 in flag):
          return False;
      else:
          flag.append(c % 10)

      a = (int) (a / 10)
      b =(int) (b / 10)
      c = (int) (c / 10)
     # print(flag)
  return True

if __name__ == '__main__':

  ans = 0

  for a in range(123, 987):
      for b in range(123, 987 - a):
          c = a + b
          if (check(a, b, c)):
              ans += 1
              print(a, "+", b, " = ", c)

  print(ans)

求值

题目描述:

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

学习了约数后,小明对于约数很好奇,他发现,给定一个正整数 t,总是可以找到含有 t 个约数的整数。小明对于含有 t 个约数的最小数非常感兴趣,并把它定义为 St​。

例如 S1=1,S2=2,S3=4,S4=6,⋅⋅⋅

现在小明想知道,当 t=100 时,S1​00 是多少?

运行限制:

  1. 最大运行时间:1s
  2. 最大运行内存:128M

题目分析

这道题乍一看,是一道数论题目,实际上他确实一道数论题目,但是由于是道填空题,所以我们采用模拟法打表做。

题目中的描述是找约数,那我们定义个找约束个数的函数,然后枚举即可。

这样不考虑时间复杂度,我们采取暴力法,尽快完成题目,让程序去跑答案,节省下时间来去做其他的题目。

我们可以这样暴力写约束计数函数。

代码

def cnt(a):
    ans=0

    for j in range(1,a+1):
        if a%j ==0:
            ans+=1
    return   ans

if __name__ == '__main__':

    for i in range(1,400000):
        if cnt(i)==100:
            print(cnt(i),' ',i)
            break

既约分数

题目描述:

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如:3/4、1/8、7/1
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?

运行限制

  1. 最大运行时间:1s
  2. 最大运行内存:128M

题目解析

我们看到这种题,现在一眼就知道只是到纯暴力的题目,即暴力枚举然后依据题目要求模拟即可。

但是这种简单题在比赛中是来送分的,我们要花很少的时间做完,才有时间做其他的题目,这就要求我们对这种题目的熟练度极高,要做到,看到题目,想到思路手里能直接写出来才可以。

这里有一个巧妙的方法是因为分子与分母是对称的我们可以少枚举一半,不过有些同学可能没想明白,没关系,我们用普通的办法,只要能够快速的编程并找到答案,思路正确性能够保证的话,其他的都是可有可无的。

这题目我们首先要两个数是否互质,即最小公约数为 1,我们就定义一个 GCD() 求最小公约数的算法,这里我们采用的是递归的方法。

代码

def gcd(a, b):
    tem = 0
    while (b > 0):
        temp = b

        b = a % b

        a = temp
    return a


if __name__ == '__main__':

    ans=0
    for a in range(1, 2021):
        for b in range(1, 2021):
            if gcd(a,b)==1 :
                ans+=1

    print(ans)

天干地支

题目描述:

古代中国使用天干地支来记录当前的年份。

天干一共有十个,分别为:甲(jiǎ)、乙(yǐ)、丙(bǐng)、丁(dīng)、戊(wù)、己(jǐ)、庚(gēng)、辛(xīn)、壬(rén)、癸(guǐ)。

地支一共有十二个,分别为:子(zǐ)、丑(chǒu)、寅(yín)、卯(mǎo)、辰(chén)、巳(sì)、午(wǔ)、未(wèi)、申(shēn)、酉(yǒu)、戌(xū)、 亥(hài)。

将天干和地支连起来,就组成了一个天干地支的年份,例如:甲子。

2020 年是庚子年。

每过一年,天干和地支都会移动到下一个。例如 2021 年是辛丑年。

每过 60 年,天干会循环 6 轮,地支会循环 5 轮,所以天干地支纪年每 60 年轮回一次。例如 1900 年,1960 年,2020 年都是庚子年。

给定一个公元纪年的年份,请输出这一年的天干地支年份。

输入描述:

输入一行包含一个正整数,表示公元年份。

其中有 ,输入的公元年份为不超过 9999 的正整数。

输出描述:

输入一行包含一个正整数,表示公元年份。

输入输出样例:

输入

2020

输出

gengzi

运行限制

  1. 最大运行时间:1s
  2. 最大运行内存: 128M

题目解析

这个题目是模拟法中最讨厌也最常见的一种,可能还有比这更复杂的,但这道题,已经初具代表性。

他的种类比较多,天干就有 10 种 ,地支有 12 种

现在我们知道了 2020 年是庚子年,我们这里既可以是除留余数来判断 N 年是什么天干和什么地支,我们也可以直接暴力使用循环做,这样的话 9999 的复杂度也跑不了多久。实现起来很简单,我们讲这个比较难的。

我们先判断 0000 年的天干 和地支 。

根据题意 0000 年 距 2020 年 早了 2020 年 。
已知天干 有 10 个, 那么 2020%10=0 剩下的都是整个轮回,即到了 0000 年 是庚 X 年,即天干是 庚 。
再按照这个方法算地支 是 2020%12=4 及还要向前推四年 地支为申。

即 0000 年为庚申年,那么根据模拟法可知。

N%10=0 时 天干为庚

N%10=1 时 天干为辛

以此类推

N%12=0 时 地支为申

N%12=1 时 地支为酉 …

以此类推:

那我们很容易就能实现判断代码的编写:

代码

tg = ["geng", "xin", "ren", "gui", "jia", "yi", "bing", "ding", "wu", "ji"]
dz = ["shen", "you", "xu", "hai", "zi", "chou",
      "yin", "mou", "chen", "si", "wu", "wei"]

if __name__ == '__main__':
    
year = int(input())
print(tg[year % 10], dz[year % 12], sep='')
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

啥都鼓捣的小yao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值