一.简介
模拟就是用计算机来模拟题目中要求的操作。
模拟题目通常具有码量大、操作多、思路繁复的特点。由于它码量大,经常会出现难以查错的情况,如果在考试中写错是相当浪费时间的。
二.技巧
写模拟题时,遵循以下的建议有可能会提升做题速度:
- 在动手写代码之前,在草纸上尽可能地写好要实现的流程。
- 在代码中,尽量把每个部分模块化,写成函数、结构体或类。
- 对于一些可能重复用到的概念,可以统一转化,方便处理:如,某题给你 "YY-MM-DD 时:分" 把它抽取到一个函数,处理成秒,会减少概念混淆。
- 调试时分块调试。模块化的好处就是可以方便的单独调某一部分。
- 写代码的时候一定要思路清晰,不要想到什么写什么,要按照落在纸上的步骤写。
实际上,上述步骤在解决其它类型的题目时也是很有帮助的。
三.例题
题目一:
一只长度不计的蠕虫位于n英寸深的井的底部。它每次向上爬u英寸,但是必须休息一次才能再次向上爬。在休息的时候,它滑落了d英寸。之后它将重复向上爬和休息的过程。蠕虫爬出井口需要至少爬多少次?如果蠕虫爬完后刚好到达井的顶部,我们也设作蠕虫已经爬出井口。
解题分析:
我们只需要编写程序,模拟蠕虫的爬行,根据题目要求添加结束条件即可得到问题的解。n为蠕虫需爬行的总距离,我们可以设置一个循环模拟蠕虫爬行,循环每次先爬行u,使得剩余距离-u,再滑落d,即剩余距离+d。爬行结束只会发生在u过程中,当爬行u过程中或结束时,剩余距离0(即总爬行距离达到n)则完成了爬行。
# Python
u, d, n = map(int, input().split())
time = dist = 0
while True: # 用死循环来枚举
dist += u
time += 1
if dist >= n: # 满足条件则退出死循环
break
dist -= d
print(time) # 输出得到的结果
题目二:
给定一个整数数组 asteroids,表示在同一行的行星。
对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动)。每一颗行星以相同的速度移动。
找出碰撞后剩下的所有行星。碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。
示例 1:
输入:asteroids = [5,10,-5]
输出:[5,10]
解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。
示例 2:输入:asteroids = [8,-8]
输出:[]
解释:8 和 -8 碰撞后,两者都发生爆炸。
示例 3:输入:asteroids = [10,2,-5]
输出:[10]
解释:2 和 -5 发生碰撞后剩下 -5 。10 和 -5 发生碰撞后剩下 10 。
解题思路:
这里我们模拟行星的运动,首先我们容易得到以下结论
- 同向移动行星无法发生碰撞
- 异向行星可能发生碰撞,必须正行星在左,负行星在右。
易推,只有右边的负行星会与左边的正行星发生碰撞这一种碰撞情况
我们从左至右遍历行星,也相当于视线向右运动,所以我们以向右运动的正数行星为参考。用一个栈记录视线遍历过发生碰撞后剩余的行星
当遍历到正的行星(方向向右),一定不会和栈中行星发生碰撞,我们将这颗行星加入栈中:因为行星向右,首先不可能与栈中负行星碰撞,因为负行星在左边向左移动,对于栈正行星也不会发生碰撞,因为行星移动速度一致,同向行星无法追上彼此碰撞
当遍历到负行星时分情况进行碰撞判断讨论:
- 当栈中没有行星时,不满足右负左正的碰撞条件,直接将负行星加入栈,结束碰撞判断
- 当栈顶(最右侧)是负行星时,不满足右负左正碰撞条件,可直接将负行星入栈,结束碰撞判断
- 当栈顶是正行星时,满足碰条件,发生碰撞。1.如果正行星体积大,该负行星爆炸,不执行任何操作,结束碰撞判断;2.如果负行星体积大,取出栈顶正行星(相当于该行星爆炸),继续进行该负行星的下一轮碰撞判断;3.行星体积相等,取出栈顶正行星,结束碰撞判断
在代码中,我们用一个变量alive记录该负行星是否需要入栈
class Solution:
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
stars = []
for i in asteroids:
if i > 0:
stars.append(i)
else:
alive = True
while stars:
right = stars.pop()
if right < 0:
stars.append(right)
break
else:
if right > abs(i):
stars.append(right)
alive = False
break
elif right + i == 0:
alive = False
break
if alive:
stars.append(i)
return stars