当前位置: 首页 > news >正文

P1202 [USACO1.1] 黑色星期五Friday the Thirteenth

题目描述

13 13 13 号又是一个星期五,那么 13 13 13 号在星期五比在其他日子少吗?

为了回答这个问题,写一个程序,要求计算每个月的十三号落在周一到周日的次数。给出 n n n 年的一个周期,要求计算 1900 1900 1900 1 1 1 1 1 1 日至 1900 + n − 1 1900+n-1 1900+n1 12 12 12 31 31 31 日中十三号落在周一到周日的次数。

这里有一些你要知道的:

  1. 1900 1900 1900 1 1 1 1 1 1 日是星期一。
  2. 4 , 6 , 11 4,6,11 4,6,11 9 9 9 月有 30 30 30 天,其他月份除了 2 2 2 月都有 31 31 31 天,闰年 2 2 2 月有 29 29 29 天,平年 2 2 2 月有 28 28 28 天。
  3. 年份可以被 4 4 4 整除的为闰年( 1992 = 4 × 498 1992=4\times 498 1992=4×498 所以 1992 1992 1992 年是闰年,但是 1990 1990 1990 年不是闰年)。
  4. 以上规则不适合于世纪年。可以被 400 400 400 整除的世纪年为闰年,否则为平年。所以, 1700 , 1800 , 1900 , 2100 1700,1800,1900,2100 1700,1800,1900,2100 年是平年,而 2000 2000 2000 年是闰年。

输入格式

一个正整数 n n n

输出格式

依次输出周六、日、一、二、三、四、五在 13 13 13 日出现的次数。

输入输出样例 #1

输入 #1

20

输出 #1

36 33 34 33 35 35 34

说明/提示

【数据范围】:对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 400 1\le n \le 400 1n400

USACO Training Section 1.1

提交链接

Friday the Thirteenth

思路分析

✅ 总体思路

本题要求统计从 1900 1900 1900 1 1 1 1 1 1 日开始,连续 n n n 年 中,每个月的 13 13 13 号是星期几的次数,并按照指定顺序输出每个星期几出现的次数。

采用模拟法,从 1900 1900 1900 1 1 1 1 1 1 日开始,逐月推进,通过取模计算每月 13 13 13 号是星期几,并用数组统计每个星期几出现的频率。

🔍 逐步分析

1️⃣ 定义变量与判断闰年函数

int num[7];
  • n u m [ i ] num[i] num[i] 表示星期 i i i 上出现 13号 的次数

  • 星期编号:0=周日1=周一,…,6=周六

bool is_year(int x)
{return (x % 4 == 0 && x % 100 != 0) || x % 400 == 0;
}
  • 判断年份 x x x 是否是闰年

  • 遵循闰年规则:能被 4 4 4 整除但不能被 100 100 100 整除,或能被 400 400 400 整除

2️⃣ 每月天数判断函数 solve

int solve(int x , int y)
  • 返回 x x x y y y 月的天数

  • 2 2 2月特殊处理,调用 is_year() 判断是否是闰年

  • 4 4 4 6 6 6 9 9 9 11 11 11 月为 30 30 30 天,其余为 31 31 31

3️⃣ 主函数逻辑

int day = 1; // 1900年1月1日是周一
  • day 表示当前月份的 1 1 1 号是星期几;

  • 使用取模来推进计算,(day + 12) % 7 表示本月 13 13 13 号是星期几

4️⃣ 双层循环:年份 & 月份推进

for (int i = 1900; i <= 1900 + n - 1; i++) 
{for (int j = 1; j <= 12; j++) {int k = (day + 12) % 7;num[k]++;day = (day + solve(i , j)) % 7;}
}
  • i i i 1900 1900 1900 年开始循环 n n n

  • j j j 1 1 1 月到 12 12 12

  • (day + 12) % 7:当前月份 13 13 13 号是星期几

  • num[k]++:统计这个星期几出现了一个 “13号”

  • day = (day + 天数) % 7:推算下个月 1 1 1 号是星期几

5️⃣ 输出结果

cout << num[6] << " " << num[0];
for(int i = 1; i <= 5; i++)cout << " " << num[i];
  • 题目要求输出顺序为:周六 周日 周一 周二 周三 周四 周五;

  • 因为 0 = 周日, 1 = 周一, ..., 6 = 周六,所以输出顺序就是:
    num[6], num[0], num[1], ..., num[5]

完整代码:

#include <bits/stdc++.h>
using namespace std;int num[7];
bool is_year(int x)
{if (x % 4 == 0 && x % 100 != 0 || x % 400 == 0)return true;return false;
}int solve(int x , int y)
{if(y == 2)return is_year(x) ? 29 : 28;else if(y == 4 || y == 6 || y == 9 || y == 11)return 30;elsereturn 31;
}
int main()
{int n;cin >> n;int day = 1;  //每月的1号为周几   初始为周一for (int i = 1900; i <= 1900 + n - 1; i++){for (int j = 1; j <= 12; j++){//每一个月的13号 判断周几?int k = (day + 12) % 7;num[k]++;day = (day + solve(i , j)) % 7;  //下月1号星期几}}cout << num[6] << " " << num[0];for(int i = 1; i <= 5; i++)cout << " " << num[i];return 0;
}
http://www.dtcms.com/a/266197.html

相关文章:

  • Ubuntu Linux Cursor 安装与使用一
  • 成功解决运行:Django框架提示:no such table: django_session
  • 基于探索C++特殊容器类型:容器适配器+底层实现原理
  • 如何通过注解(@Component 等)声明一个 Bean?Spring 是如何找到这些注解的?
  • java微服务(Springboot篇)——————IDEA搭建第一个Springboot入门项目
  • 【基础算法】贪心 (二) :推公式
  • 封装一个png的编码解码操作
  • 译码器Multisim电路仿真汇总——硬件工程师笔记
  • 嵌入式系统中实现串口重定向
  • 【模糊集合】示例
  • 【MySQL\Oracle\PostgreSQL】迁移到openGauss数据出现的问题解决方案
  • Qt Creator自定义控件开发流程
  • redis缓存三大问题分析与解决方案
  • 车载以太网都有什么协议?
  • 创建 TransactionStatus
  • 【STM32实践篇】:I2C驱动编写
  • NumPy 安装使用教程
  • Debian-10-standard用`networking`服务的`/etc/network/interfaces`配置文件设置多网卡多IPv6
  • 【2.4 漫画SpringBoot实战】
  • CMake之CMakeLists.txt语法规则
  • 网安系列【1】:黑客思维、技术与案例解析
  • DDD实战:CQRS模式在电商报表系统中的高性能实践
  • RNN案例人名分类器(完整步骤)
  • MySQL 8.0 OCP 1Z0-908 题目解析(17)
  • POST请求url放参数场景-笔记
  • Spring SseEmitter 系统详细讲解
  • WPF学习笔记(16)树控件TreeView与数据模板
  • WPF学习笔记(22)项面板模板ltemsPanelTemplate与三种模板总结
  • spring-ai-alibaba 1.0.0.2 学习(八)——接入阿里云信息查询服务
  • 深度学习-逻辑回归