昨天参加了传智杯的练习赛,里面有一题卡了我很久,今天整理一下记录到博客。

文章目录

  • 题目描述
  • 输入格式
  • 输出格式
  • 样例
  • 思路
    • 变量定义
    • 接受输入
    • 第一部分
    • 第二部分
    • 输出
  • 代码实现

题目描述

输入格式

按照 日月年 的格式输入数据,其中日是 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. 将年份-1进行计算经过的闰年数
  2. ans赋值为(年份-1)*365+闰年数
  3. ans += 这一年的月份 - 1的总天数
  4. 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 儒略历详解相关推荐

  1. 洛谷千题详解 | P1008 [NOIP1998 普及组] 三连击【C++、Java、Python语言】

    博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: Java源码: Python源码: ----------------------- ...

  2. 洛谷千题详解 | P1014 [NOIP1999 普及组] Cantor 表【C++、Java语言】

    博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: C++源码2: C++源码3: Java源码: ----------------- ...

  3. 洛谷千题详解 | P1010 [NOIP1998 普及组] 幂次方【C++、Java、Python、Pascal语言】

    博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: Pascal源码: Java源码: Python源码: ------------- ...

  4. 洛谷——T156530 儒略历

    T156530 儒略历 题目链接:T156530 儒略历 题目描述 在 1582 年之前,以 4 为倍数的年份为闰年.正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, ...

  5. 洛谷 T156530 儒略历(传智杯-练习赛)

    T156530 儒略历 题目描述 在 1582 年之前,以 4 为倍数的年份为闰年.正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, 30, 31, 31, 30, ...

  6. 洛谷 题解 P2312 【解方程】

    Problem P2312 [解方程] >>> record 用时: 1166ms 空间: 780KB(0.76MB) 代码长度: 2.95KB 提交记录: R9909587 > ...

  7. 洛谷 2312 / bzoj 3751 解方程——取模

    题目:https://www.luogu.org/problemnew/show/P2312 https://www.lydsy.com/JudgeOnline/problem.php?id=3751 ...

  8. 【洛谷】P1830 轰炸III 题解 代码+详解

    这里是Jane的OJ解答之洛谷系列~ (放假啦 尽量日更叭ε≡٩(๑>₃<)۶ ) 来分享一些算法和题解,一般用的都是C语言,还在学C++ |ू・ω・` ) 如果内容有问题,欢迎大家私信 ...

  9. 洛谷日常刷题(洛谷官方题单 思路+详解)

    目录 前言 非官方题单的题 P1141 01迷宫 1-4 递推与递归 P1255 数楼梯 1002 [ NOIP 2002 普及组]过河卒 P1044 [NOIP2003 普及组] 栈 P1028 [ ...

最新文章

  1. Linux基础-兄弟连Linux
  2. python装饰器实例-python 装饰器(三):装饰器实例(一)
  3. 大势至电脑文件防泄密软件_有了数据防泄密软件,还会担心企业文件泄漏吗?...
  4. Eclipse中SVN标记,提交人,时间等版本信息消失
  5. koa2+html模板,lenneth -- 基于koa2 的web极简框架
  6. 专业的统计分析软件 IBM SPSS Statistics 26 Mac版(附带安装包网盘资源)
  7. CenterOs git安装
  8. chrome浏览器打开axure原型图的方法
  9. 老版本xcode下载_iOS秘籍】-下载历史版本App超详细教程
  10. 苹果7plus元件分布图_苹果iPhone7Plus元件分布图+电路原理图+位置图PDF
  11. vue 日程表组件_vue 会议日程列表
  12. pwn unlink
  13. 链乔教育在线|数字化工作管理工具—Notion(四):同步块(Synced block)
  14. Chrome打包扩展程序错误,清单文件缺失或不可读
  15. 【超详细】使用Oracle VM VirtualBox 搭建一个Linux虚拟机
  16. 服务器 进 pe系统安装系统安装系统,用U盘安装系统之PE安装.doc
  17. Data Mining Machine Learning学习笔记 机器学习入门笔记 之jieba分词(中文分词)(二)
  18. 渣基础:比照Hawstein学Cracking the coding interview(1)
  19. volatile禁止重排序详解
  20. 学了一阵子python pygame, 写一些总结,回头看看哪些地方不足

热门文章

  1. 2014小米,百度,pptv,去哪儿笔试题目回忆
  2. MFC的Dlg和App什么区别?应用程序类与对话框类
  3. slam学习(1)——卡尔曼滤波
  4. 传智播客开课的第四天
  5. pythonjam游戏_独游网 - 专注独立游戏,为独立游戏发声!
  6. syntax error, expect [, actual {, pos 0, fieldName null解决方法
  7. 为什么我推荐你一定要学Python?
  8. 辨析 可交付成果验收与项目验收
  9. 穿越美丽秋色---黄草梁
  10. 程序员送给对象的生日礼物