洛谷T156530 儒略历详解
昨天参加了传智杯的练习赛,里面有一题卡了我很久,今天整理一下记录到博客。
文章目录
- 题目描述
- 输入格式
- 输出格式
- 样例
- 思路
- 变量定义
- 接受输入
- 第一部分
- 第二部分
- 输出
- 代码实现
题目描述
输入格式
按照 日月年 的格式输入数据,其中日是 1 到 31 之间的整数,月是三个大写字母,年是 1 到 9999 之间的整数。保证这个日期是合法且存在的。
月份的大写字母:
1月:JAN
2月:FEB
3月:MAR
4月:APR
5月:MAY
6月:JUN
7月:JUL
8月:AUG
9月:SEP
10月:OCT
11月:NOV
12月:DEC
输出格式
输出一个整数表示答案
样例
输入 | 输出 | |
---|---|---|
1 | 1JAN1 | 0 |
2 | 4OCT1582 | 577736 |
3 | 15OCT1582 | 577737 |
4 | 21NOV2020 | 737751 |
思路
这道题我分成了两部分,一部分处理年份在1582及之前的,另一部分处理年份大于1582的。
变量定义
首先是接受输入的三个变量
int year, month, day;
string strMonth = "???";
然后是记录答案的变量
int ans;
最后定义一个数组来记录月份的天数
int months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
接受输入
cin >> day;
strMonth[0] = cin.get(), strMonth[1] = cin.get(), strMonth[2] = cin.get();
cin >> year;
month = toIntMonth(strMonth);
因为输入的月份是英文的不便于计算,所以设计函数(toIntMonth)将其转化为整型月份
int toIntMonth(string m) {if (m == "JAN") return 1;else if (m == "FEB") return 2;else if (m == "MAR") return 3;else if (m == "APR") return 4;else if (m == "MAY") return 5;else if (m == "JUN") return 6;else if (m == "JUL") return 7;else if (m == "AUG") return 8;else if (m == "SEP") return 9;else if (m == "OCT") return 10;else if (m == "NOV") return 11;else if (m == "DEC") return 12;return 0;
}
第一部分
这一部分处理的是1582及之前年份。
计算步骤如下:
- 将年份-1进行计算经过的闰年数
- ans赋值为(年份-1)*365+闰年数
- ans += 这一年的月份 - 1的总天数
- ans += day
代码如下
if (year <= 1582) {//之前年份的日数year--;ans = year * 365 + getLeepYearCount1(year);year++;//获取之前月份的日数 + 当前月份的日数ans += getDayByMonth(month - 2, isLeepYear1(year)) + day;//1582年份的特殊判断if (year == 1582) {//在[1582.10.5, 1582.10.14]之间的特殊天数(不记录)if (month == 10 && day > 4 && day < 15) ans -= day - 4;//在1582.10.15日及之后该年剩下的日子-10天,因为10月的5-14日不存在else if ((month == 10 && day >= 15) || (month > 10)) ans -= 10;}
}
其中getLeepYearCount1的功能是计算1到当前年份(1582之前)的闰年数量
int getLeepYearCount1(int y) {return y / 4;
}
isLeepYear1是用来判断这一年(1582年之前)是否为闰年
bool isLeepYear1(int y) {return y % 4 == 0;
}
getDayByMonth是获取这一年中经过的天数(r代表是否为闰年)
int getDayByMonth(int mon, bool r) {if (mon < 0) return 0; if (r) months[1]++;for (int i = 1; i <= mon; i++) {months[i] += months[i - 1];}return months[mon];
}
第二部分
这一部分处理的是1582之后的年份。
计算步骤如下和第一部分差不多:
else {//之前年份的日数year--;ans = year * 365 + getLeepYearCount2(year);year++;//获取之前月份的日数 + 当前月份的日数 - 10(十天是因为1582年10月的5-14日不存在)ans += getDayByMonth(month - 2, isLeepYear2(year)) + day - 10;
}
isLeepYear2是用来判断这一年(1582年之后)是否为闰年
bool isLeepYear2(int y) {return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}
getLeepYearCount2和getLeepYearCount1差不多,只不过在1582年之后采用新的计算方式
int getLeepYearCount2(int y) {int c = 0;for (int i = 1582; i <= y; i++) {if (isLeepYear2(i)) {c++;}}//395是1582年之前的闰年数return c + 395;
}
输出
cout << ans - 1;
这里减一是因为距离公元1.1.1的天数不包括今天的
代码实现
#include <bits/stdc++.h>using namespace std;int months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int toIntMonth(string m) {if (m == "JAN") return 1;else if (m == "FEB") return 2;else if (m == "MAR") return 3;else if (m == "APR") return 4;else if (m == "MAY") return 5;else if (m == "JUN") return 6;else if (m == "JUL") return 7;else if (m == "AUG") return 8;else if (m == "SEP") return 9;else if (m == "OCT") return 10;else if (m == "NOV") return 11;else if (m == "DEC") return 12;return 0;
}int getDayByMonth(int mon, bool r) {if (mon < 0) return 0; if (r) months[1]++;for (int i = 1; i <= mon; i++) {months[i] += months[i - 1];}return months[mon];
} bool isLeepYear1(int y) {return y % 4 == 0;
}int getLeepYearCount1(int y) {return y / 4;
}bool isLeepYear2(int y) {return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}int getLeepYearCount2(int y) {int c = 0;for (int i = 1582; i <= y; i++) {if (isLeepYear2(i)) {c++;}}//395是1582年之前的闰年数return c + 395;
}int main() {int year, month, day;string strMonth = "???";int ans;cin >> day;strMonth[0] = cin.get(), strMonth[1] = cin.get(), strMonth[2] = cin.get();cin >> year;month = toIntMonth(strMonth);if (year <= 1582) {//之前年份的日数year--;ans = year * 365 + getLeepYearCount1(year);year++;//获取之前月份的日数 + 当前月份的日数ans += getDayByMonth(month - 2, isLeepYear1(year)) + day;//1582年份的特殊判断if (year == 1582) {//在[1582.10.5, 1582.10.14]之间的特殊天数(不记录)if (month == 10 && day > 4 && day < 15) ans -= day - 4;//在1582.10.15日及之后该年剩下的日子-10天,因为10月的5-14日不存在else if ((month == 10 && day >= 15) || (month > 10)) ans -= 10;}} else {//之前年份的日数year--;ans = year * 365 + getLeepYearCount2(year);year++;//获取之前月份的日数 + 当前月份的日数 - 10(十天是因为1582年10月的5-14日不存在)ans += getDayByMonth(month - 2, isLeepYear2(year)) + day - 10; }cout << ans - 1;return 0;
}
洛谷T156530 儒略历详解相关推荐
- 洛谷千题详解 | P1008 [NOIP1998 普及组] 三连击【C++、Java、Python语言】
博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: Java源码: Python源码: ----------------------- ...
- 洛谷千题详解 | P1014 [NOIP1999 普及组] Cantor 表【C++、Java语言】
博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: C++源码2: C++源码3: Java源码: ----------------- ...
- 洛谷千题详解 | P1010 [NOIP1998 普及组] 幂次方【C++、Java、Python、Pascal语言】
博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: Pascal源码: Java源码: Python源码: ------------- ...
- 洛谷——T156530 儒略历
T156530 儒略历 题目链接:T156530 儒略历 题目描述 在 1582 年之前,以 4 为倍数的年份为闰年.正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, ...
- 洛谷 T156530 儒略历(传智杯-练习赛)
T156530 儒略历 题目描述 在 1582 年之前,以 4 为倍数的年份为闰年.正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, 30, 31, 31, 30, ...
- 洛谷 题解 P2312 【解方程】
Problem P2312 [解方程] >>> record 用时: 1166ms 空间: 780KB(0.76MB) 代码长度: 2.95KB 提交记录: R9909587 > ...
- 洛谷 2312 / bzoj 3751 解方程——取模
题目:https://www.luogu.org/problemnew/show/P2312 https://www.lydsy.com/JudgeOnline/problem.php?id=3751 ...
- 【洛谷】P1830 轰炸III 题解 代码+详解
这里是Jane的OJ解答之洛谷系列~ (放假啦 尽量日更叭ε≡٩(๑>₃<)۶ ) 来分享一些算法和题解,一般用的都是C语言,还在学C++ |ू・ω・` ) 如果内容有问题,欢迎大家私信 ...
- 洛谷日常刷题(洛谷官方题单 思路+详解)
目录 前言 非官方题单的题 P1141 01迷宫 1-4 递推与递归 P1255 数楼梯 1002 [ NOIP 2002 普及组]过河卒 P1044 [NOIP2003 普及组] 栈 P1028 [ ...
最新文章
- Linux基础-兄弟连Linux
- python装饰器实例-python 装饰器(三):装饰器实例(一)
- 大势至电脑文件防泄密软件_有了数据防泄密软件,还会担心企业文件泄漏吗?...
- Eclipse中SVN标记,提交人,时间等版本信息消失
- koa2+html模板,lenneth -- 基于koa2 的web极简框架
- 专业的统计分析软件 IBM SPSS Statistics 26 Mac版(附带安装包网盘资源)
- CenterOs git安装
- chrome浏览器打开axure原型图的方法
- 老版本xcode下载_iOS秘籍】-下载历史版本App超详细教程
- 苹果7plus元件分布图_苹果iPhone7Plus元件分布图+电路原理图+位置图PDF
- vue 日程表组件_vue 会议日程列表
- pwn unlink
- 链乔教育在线|数字化工作管理工具—Notion(四):同步块(Synced block)
- Chrome打包扩展程序错误,清单文件缺失或不可读
- 【超详细】使用Oracle VM VirtualBox 搭建一个Linux虚拟机
- 服务器 进 pe系统安装系统安装系统,用U盘安装系统之PE安装.doc
- Data Mining Machine Learning学习笔记 机器学习入门笔记 之jieba分词(中文分词)(二)
- 渣基础:比照Hawstein学Cracking the coding interview(1)
- volatile禁止重排序详解
- 学了一阵子python pygame, 写一些总结,回头看看哪些地方不足