把每天模拟改成按工资段累加,每段贡献为实际天数乘当前金币数。
OJ: luogu
题目 ID: P2669
难度:入门
标签:模拟数学循环python
日期: 2026-06-18 20:48
题意
第 1 段连续 1 天每天发 1 枚金币,第 2 段连续 2 天每天发 2 枚金币,第 3 段连续 3 天每天发 3 枚金币,依次类推。
给出天数 k,求前 k 天总共发了多少枚金币。
思路
可以逐天模拟,但更直接的做法是按“段”处理:
- 当前段金币数是
value; - 这一段最多持续
value天; - 如果剩余天数不足一整段,就只取剩下的
k天; - 本段贡献是
days * value。
因此每轮取:
text
days = min(剩余天数, 当前段长度)然后把 days * value 加入答案,并减少剩余天数。循环结束时,所有前 k 天都已经统计完。
这是一道直接模拟题。Python 教学版不创建 brute.py,因为逐天暴力和分段模拟都在表达同一个发放规则,额外代码对理解帮助不大。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:使用int(input())读取单个整数。/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md:这里用到整数乘法和min,Python 的int不会溢出。while k > 0:可以把k直接作为“剩余未处理天数”,每轮让它减少。min(k, value)是处理最后一段不完整情况的常见写法。
代码
python
k = int(input())
answer = 0
value = 1
while k > 0:
days = min(k, value)
answer += days * value
k -= days
value += 1
print(answer)Pythonic 写法
按天发金币:
python
k=int(input())
day=coin=total=0
while total<k:
day+=1
for _ in range(day):
if total>=k: break
coin+=day; total+=1
print(coin)复杂度
循环次数等于处理过的工资段数,大约是
总结
把“每天发多少”改写成“每一段贡献多少”,代码会比逐天模拟更短,也自然处理最后一段不足整段的情况。