【深基7.例3】闰年展示

封装闰年判断函数,枚举区间内年份并筛出所有闰年。

OJ: luogu

题目 ID: P5737

难度:入门

标签:模拟函数枚举python

日期: 2026-07-15 21:08

题意

给定年份区间 [x, y],输出其中闰年的个数,并按升序输出所有闰年。

思路

闰年规则是:

text
能被 400 整除,或者能被 4 整除但不能被 100 整除。

把这个判断写成函数 is_leap_year(year),再枚举 startend 的所有年份,保留满足条件的年份。

这题是函数和区间枚举练习,不创建 brute.py

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:一行两个整数用 map(int, input().split())
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/generator_expression.md:列表推导式适合从区间中筛选结果。
  • range(start, end + 1) 表示闭区间 [start, end]
  • orand 可以直接表达闰年规则。

代码

python
def is_leap_year(year):
    return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)


start, end = map(int, input().split())
years = [year for year in range(start, end + 1) if is_leap_year(year)]

print(len(years))
print(*years)
cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int leap[2005]; // 存储闰年年份
int cnt;       // 闰年个数

// 判断是否为闰年
bool is_leap(int y) {
    return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}

int main() {
    int l, r;
    cin >> l >> r;
    for (int y = l; y <= r; y++) {
        if (is_leap(y)) leap[++cnt] = y;
    }
    cout << cnt << "\n";
    for (int i = 1; i <= cnt; i++) cout << leap[i] << " ";
    return 0;
}

Guide 风格代码

cppbook《C++ 快速入门》教学风格的写法(std:: 前缀、i += 1 循环、0 起始下标):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-08-14 14:57
 * update_at: 2026-08-14 14:57
 */
#include <iostream>

bool is_leap(int year) {
    // 闰年:能被 400 整除,或能被 4 整除但不能被 100 整除
    return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}

int main() {
    int start, end;
    std::cin >> start >> end;

    // 区间 [1582, 3000] 内闰年最多约 350 个,预留 400 个位置
    const int max_leap_years = 400;
    int leap_years[max_leap_years];
    int count = 0;

    for (int year = start; year <= end; year += 1) {
        if (is_leap(year)) {
            leap_years[count] = year;
            count += 1;
        }
    }

    // 第一行输出个数,第二行按从小到大输出所有闰年
    std::cout << count << '\n';
    for (int i = 0; i < count; i += 1) {
        std::cout << leap_years[i] << ' ';
    }
    return 0;
}

Pythonic 写法

列表推导筛闰年:

python
start, end = map(int, input().split())
years = [y for y in range(start, end + 1) if y % 400 == 0 or (y % 4 == 0 and y % 100 != 0)]
print(len(years))
print(*years)

复杂度

设区间长度为 L = y - x + 1,时间复杂度是 O(L)O(L),空间复杂度是 O(L)O(L)

总结

遇到有明确判定规则的题,先把规则封装成布尔函数,再用枚举筛选,主流程会很清楚。