引:

如果你见到一个oi对着 47131582 146097 2299160 颠颠地笑,不用怀疑,他是在做那道名题--《csp-s2020 T1 儒略日》

这道题,我做了三年,平均每年做一次,我来讲讲我的心得。

读题

题面很长,细节很多,我们需要耐心细心的读,此时多花一点时间是划得来的。

我们得出大致关系如下

\[历法\begin{cases}
\begin{aligned}
公历(日常用历)\\
\\

\\
儒略历 \begin{cases} 公元前\\公元后\\\end{cases}
\end{aligned}
\end{cases}
\]

\[
我们对公历都有一定的了解吧,比如 平年十二个月的天数, 比如小学教的 “一三五七八十腊”,四年一闰百年不闰四百年又闰,这些宝贵的经验将成为我们解题的关键说的呢。

格里高利相较于公历其实更为简单,~~因为太简单不准所以才改的嘛~~ ,就是闰年的计算规则不同,是每四年一闰。

## 解题

首先,这是一道人尽皆知的模拟题。模拟的概念太笼统了,实现起来也八仙过海,我来讲讲我觉得最适合入手这道关于日期的大模拟。

#### 解题的方向

我们要想着化繁为简,一个劲的分类讨论不见得总是好事(我第一次就这么G的)。

多想想在 coding , 写代码的时间总是小于调 bug 的时间的。

### 我的思路

我们发现,将日期分为儒略历和公历是比较好的,将公元前的日期归化到儒略历的一部分,不用特殊处理,具体来讲,将公元前的日期年份 $y$ $->$ $\ -y + 1$ 比如BC 4713 变为 -4712 ,这阳处理闰年也方便。

我们来算一下儒略历一共多少天

首先公元前天数 `365 * 4713 + 4713 / 4`

公元后的天数`1581 * 365 + 1581 / 4 + 277 ` 1582(不含)年以前的和1582年的277天。

总共 `2299160` 天。

对于较简单的儒略历,我们可以直接算

```cpp
int y = -4712, m = 1, d = 1;
if (x <= Ru) {
y += x / (_1 * 4 + 1) * 4;
x %= (_1 * 4 + 1);
while(x >= (_1 + (y % 4 == 0))) x -= (_1 + (y % 4 == 0)), y++;
while(x >= (M[m] + (m == 2 && y % 4 == 0))) x -= (M[m] + (m == 2 && y % 4 == 0)), m++;
d += x;
if (y < 1) {
cout << d << ' ' << m << ' ' << 1 - y << ' ' << "BC" << endl;
} else {
cout << d << ' ' << m <<' ' << y << endl;
}
}
```

代码中`(M[m] + (m == 2 && y % 4 ==0)` 是处理闰年的二月日期(28->29)

注意的是, 1 1 4713 BC 是第0天

对于周期的存储,我们可以这样//公历下

```cpp
int _1 = 365, _4 = 4 * _1 + 1, _100 = 25 * _4 - 1, _400 = _100 * 4 + 1; //100,400是公历下的
int M[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
```

对于公历, 我们考虑将1582 10 15 到 1982 10 14日这400年打一个小表,这样极大简化了我们的计算量

```cpp
else {
x -= Ru;
y = 0;
y += x / _400 * 400; x %= _400;
cout << a[x].d << ' ' << a[x].m << ' ' << y + a[x].y << endl;
}
```

其中a是打出来的表,a[x]是四百年中的第几天,10月15 日算第一天。

那么,怎么打出这个表?

答:~~用手打~~ 可以用结构体。

```cpp
struct dt{
int y, m, d;
dt(){}
dt(int _y, int _m, int _d) {
y = _y, m = _m, d = _d;
}
}a[maxn], be = {1582, 10, 15};
```

然后四百年迭代一遍

```cpp
dt v = be;
for (int i = 1; i <= _400; i++) {
a[i] = v;
nxt(v);
}
```

我们只需处理简单的一天的日期跳转

```cpp
void nxt(dt &x) {
x.d++;
if (x.d > (M[x.m] + ck(x))) {
x.d -= (M[x.m] + ck(x));
x.m++;
}
if (x.m > 12) {
x.m = 1;
x.y++;
}
}
```

ck 是处理闰年二月

```cpp
bool ck(dt x) {
if (x.y % 4 == 0 && x.y % 100 != 0 || x.y % 400 == 0) {
return x.m == 2;
} else return 0;
}
```

于是,我们便做完了这道大模拟。

~~完结撒花!~~

没有完!还有您对作者文章的肯定/否定没有留下,可以点赞或留言,作者都会看到!

$Our\ stories\ are\ still\ going\ on.\ $\]

一道名题-(csp 儒略日)的心得与技巧的更多相关文章

  1. 玉伯的一道课后题题解(关于 IEEE 754 双精度浮点型精度损失)

    前文 的最后给出了玉伯的一道课后题,今天我们来讲讲这题的思路. 题目是这样的: Number.MAX_VALUE + 1 == Number.MAX_VALUE; Number.MAX_VALUE + ...

  2. 又一道简单题&&Ladygod(两道思维水题)

    Ladygod Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  3. 一道js题

    <script> var a = 5; function test(){ this.a = 10; a = 15 this.func = function(){ var a = 20 ; ...

  4. 每天一道Java题[3]

    问题 为什么在重写equals()方法的同时,必须重写hashCode()方法? 解答 在<每天一道Java题[2]>中,已经对hashCode()能否判断两个对象是否相等做出了解释.eq ...

  5. 每天一道Java题[11]

    题目 synchronized怎么实现线程同步?请修改<每天一道Java题[10]>中的MyRunnableThread类以解决三个线程都获取到10的问题. 解答 方法一: 采用synch ...

  6. 第三届山西省赛1004 一道大水题(scanf)

    一道大水题 时间限制: C/C++ 2000ms; Java 4000ms 内存限制: 65535KB 通过次数: 44 总提交次数: 1020 问题描述 Dr. Pan作为上兰帝国ACM的总负责人, ...

  7. ny525 一道水题

    一道水题时间限制:1000 ms  |  内存限制:65535 KB 难度:2描述 今天LZQ在玩一种小游戏,但是这游戏数有一点点的大,他一个人玩的累,想多拉一些人进来帮帮他,你能写一个程序帮帮他吗? ...

  8. 【数据结构】 最小生成树(四)——利用kruskal算法搞定例题×3+变形+一道大水题

    在这一专辑(最小生成树)中的上一期讲到了prim算法,但是prim算法比较难懂,为了避免看不懂,就先用kruskal算法写题吧,下面将会将三道例题,加一道变形,以及一道大水题,水到不用高级数据结构,建 ...

  9. 简单tarjan》一道裸题(BZOJ1051)(easy)

    这是一道水题,实际考察的是你会不会写强连通分量...(在BZOJ上又水了一道题) Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B ...

  10. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

随机推荐

  1. redis 常用指令

    redis指令有些相似,记忆起来不太容易,在此做一下整理 序号 类型 指令 参数 作用 例子 1 string set key value 存储一个 string 类型的值 set a aa 2 st ...

  2. python中的变量定义

    1 变量名:由下划线.字母和数字组成 2 python中变量名的特殊含义: xx:标准的标识符,共有的 _xx:只是在from - import *时是不会被导入的,其他导入方式会被引入 隐藏变量还有 ...

  3. 『教程』mariadb的主从复制

    一.MariaDB简介 MariaDB数据库的主从复制方案,是其自带的功能,并且主从复制并不是复制磁盘上的数据库文件,而是通过binlog日志复制到需要同步的从服务器上. MariaDB数据库支持单向 ...

  4. Ansys经验之:杨氏模量的本质概念理解——仿真在线工作记录

    Ansys经验之:什么是杨氏模量? 这是我见到的很多来培训的结构力学仿真人员的困惑,始终不能只管理解,但又是一个入门的重要概念. 本质:杨氏模量=应力/应变,即单位应变的应力.那什么叫单位应变呢,也很 ...

  5. python学习记录(六)-系统内置模块

    序列化 什么是序列化?序列化是指把python中的数据以文本或二进制形式进行转换,还能反序列化为原来的数据 为什么需要序列化?便于数据在程序与网络之间的传输和存储 json:文本序列化 pickle: ...

  6. ELK集群基础环境初始化

    集群基础环境初始化 1.准备虚拟机 192.168.1.7 192.168.1.6192.168.1.183 2.切换为国内centos源 3.修改sshd服务优化 [root@elk01 ~]# s ...

  7. 关于TCP协议传文件的例子

    按照惯例,先来进行复习,这也是自学巩固的一个过程 首先是在工程文件PRO里,需要增加network,这个是引用TCP监听套接字和连接套接字的前提 第二部,在服务端头文件server.h进行基础的配置: ...

  8. FIRE2023:殁亡漫谈

    FIRE2023:殁亡漫谈 读书的时候,想到殁亡,脑海涌出一则喜欢的遗言: 钱花完了,我走了.签名 如果可能牵涉到旁人(比如殁在旅馆里),就再立一则: 我的殁与店家无关. 签名 然后放下Kindle, ...

  9. 6. 基础查(会员信息) - 创建查询Web Api - 配置Table Permission

    ​ Power Portal中的Web API可以对门户页面中所有的Microsoft Dataverse实体进行创建.更新和删除操作.我们可以直接使用门户Web API对产品创建新客户.更新联系人或 ...

  10. 学习记录--C++组合+依赖+依赖倒置

    组合关系:表示类之间的关系是整体与部分的关系.即has a / contains a的关系 在面向对象程序设计中,将一个复杂对象分解为简单对象的组合. 在代码中,体现为将一个或多个类的对象作为另一个类 ...