{ }codelper
累加P0282

每天多读一些的读书马拉松

智宇要进行 n 天的读书马拉松。
第一天读 a 页。
从第二天起,每天读的页数是前一天读的页数加上 d。
不过一天读的页数不会超过 m 页。
如果前一天的页数加上 d 大于 m,那一天就只读 m 页。
一行给出 a、d、m、n,相邻两个数之间用一个空格隔开。
输出 n 天里读的页数的总和。

输入
1 ≤ a ≤ m ≤ 10,000,0 ≤ d ≤ 10,000,1 ≤ n ≤ 100,000(均为整数)
输出
一行,n 天读的页数总和。
只写数字,不加逗号
样例 1 · stdin
10 5 22 5
stdout
89
样例 2 · stdin
3 0 3 4
stdout
12
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

累加的写法是:在循环外面准备两个变量(今天要读的页数 pages = a,总和 total = 0),每一轮先用 total += pages 累加,再把 pages 改成明天的值。
+= 在 8 种语言里都一样。
样例 1 是 10 + 15 + 20 + 22 + 22 = 89。
取两个数中较小的:Python min(pages + d, m),JS、TS Math.min,Java Math.min,C# Math.Min,C++ std::min(<algorithm>),Craykon 数学.较小值。
C 标准库没有整数用的 min,所以写成 if (pages > m) pages = m;。
四个陷阱:① 把顺序弄反,先增加再累加,第一天的 a 页就漏掉了。
② 把存总和的变量放在循环里面创建,每一轮都会变回 0。
③ 忘了上限 m,后面的天数就会太大。
④ 天数从 1 数起却写成 day < n,最后一天就漏掉了(应写 day <= n,或从 0 数起用 day < n)。
本题的总和最大只有 1,000,000,000(十亿),放得进 Java、C#、C、C++ 的 int(约 21 亿以内)。
范围再大的话,就要累加到 long(C、C++ 是 long long)里。

Pythonmain.py · 7 行
a, d, m, n = map(int, input().split())pages = a   # 오늘 읽는 쪽수total = 0   # 지금까지 읽은 쪽수for _ in range(n):    total += pages    pages = min(pages + d, m)  # 내일 읽을 쪽수(m을 넘지 않게)print(total)
JavaScriptmain.js · 8 行
const [a, d, m, n] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let pages = a; // 오늘 읽는 쪽수let total = 0; // 지금까지 읽은 쪽수for (let day = 1; day <= n; day++) {  total += pages;  pages = Math.min(pages + d, m); // 내일 읽을 쪽수(m을 넘지 않게)}console.log(total);
TypeScriptmain.ts · 9 行
import { readFileSync } from "node:fs";const [a, d, m, n]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let pages: number = a; // 오늘 읽는 쪽수let total = 0; // 지금까지 읽은 쪽수for (let day = 1; day <= n; day++) {  total += pages;  pages = Math.min(pages + d, m); // 내일 읽을 쪽수(m을 넘지 않게)}console.log(total);
JavaMain.java · 15 行
import java.util.Scanner; public class Main {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int a = sc.nextInt(), d = sc.nextInt(), m = sc.nextInt(), n = sc.nextInt();        int pages = a;   // 오늘 읽는 쪽수        int total = 0;   // 지금까지 읽은 쪽수(가장 커도 10억이라 int에 담긴다)        for (int day = 1; day <= n; day++) {            total += pages;            pages = Math.min(pages + d, m);  // 내일 읽을 쪽수(m을 넘지 않게)        }        System.out.println(total);    }}
C#Main.cs · 18 行
using System; class Program{    static void Main()    {        string[] parts = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int a = int.Parse(parts[0]), d = int.Parse(parts[1]), m = int.Parse(parts[2]), n = int.Parse(parts[3]);        int pages = a;   // 오늘 읽는 쪽수        int total = 0;   // 지금까지 읽은 쪽수(가장 커도 10억이라 int에 담긴다)        for (int day = 1; day <= n; day++)        {            total += pages;            pages = Math.Min(pages + d, m);  // 내일 읽을 쪽수(m을 넘지 않게)        }        Console.WriteLine(total);    }}
C++main.cpp · 14 行
#include <algorithm>#include <iostream> int main() {    int a, d, m, n;    std::cin >> a >> d >> m >> n;    int pages = a;        // 오늘 읽는 쪽수    int total = 0;        // 지금까지 읽은 쪽수(가장 커도 10억이라 int에 담긴다)    for (int day = 1; day <= n; day++) {        total += pages;        pages = std::min(pages + d, m);  // 내일 읽을 쪽수(m을 넘지 않게)    }    std::cout << total << '\n';}
Cmain.c · 15 行
#include <stdio.h> int main(void) {    int a, d, m, n;    if (scanf("%d %d %d %d", &a, &d, &m, &n) != 4) return 0;    int pages = a;        // 오늘 읽는 쪽수    int total = 0;        // 지금까지 읽은 쪽수(가장 커도 10억이라 int에 담긴다)    for (int day = 1; day <= n; day++) {        total += pages;        pages += d;       // 내일 읽을 쪽수        if (pages > m) pages = m;    }    printf("%d\n", total);    return 0;}
Craykonmain.cray · 13 行
수들 = 控制台.读数字();a = 수들[0];d = 수들[1];m = 수들[2];n = 수들[3];pages = a; // 오늘 읽는 쪽수total = 0; // 지금까지 읽은 쪽수循环 (day = 1; day <= n; day++){    total += pages;    pages = 数学.较小值(pages + d, m); // 내일 읽을 쪽수(m을 넘지 않게)}控制台.输出(total);