当时考场上因为这个炸掉,一年后回来复仇。

这里提供一个与大多数人不一样的做法。

首先考虑一个简单一些的问题,怎么应付单个询问?

不难想到,我们对于一个日期,让他从 \(-4713\) 年 \(1\) 月 \(1\) 日开始,然后一年一年地加,年加不了了加月,月加不了了加日。这样很容易做,具体的细节可以看代码实现。这样就拿下了 \(50pts\)。

但是肯定不能满足于这 \(50\) 分。对于数据过大造成的TLE,我们考虑扩展我们的做法。实际上,优化的本质是重复利用之前已经求过的东西。然后可以想到从每个询问入手。可以自己先思考一下再往下看。

我们可以考虑将询问离线然后排序,每次将上一次求出的答案为起始的日期,然后重复较为暴力的算法。但是由于有的月份的上限比别的月份高,又或者 \(1582\) 年这种比较特殊的日子,我们不能直接跑暴力的操作。我们需要把起始日期再转换为 \(n\) 年 \(1\) 月 \(1\) 日 这种形式的日期,再跑暴力。这里面有一些的细节,可以自己先尝试写,再看具体代码实现。(如我的实现有问题可以私信提醒我一下,谢谢!)

发现这么写得到了 \(90pts\) 的好成绩,但是就是没切,有些许难受。没关系,我们继续优化。我们不难发现对于在 \(1852\) 年之后的日子,是满足连续 \(400\) 年的总天数是一定的,可以自己尝试算一下有多少天。

具体就是 \(146097\) 天,算法就是 \(400\times 365+100-4+1\) ,\(400\) 天里 \(100\) 个 \(4\) 的倍数,\(4\) 个 \(100\) 的倍数,\(1\) 个 \(400\) 的倍数。

然后我们在暴力操作里面在一年一年加前面加上 \(400\) 年 \(400\) 年地加,就可以愉快的 \(AC\) 了!

Code:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define filein(a) freopen(#a".in","r",stdin)
  5. #define fileot(a) freopen(#a".out","w",stdout)
  6. inline int read(){
  7. int s=0,f=1;char ch=getchar();
  8. while(ch<'0'||'9'<ch) {if(ch=='-') f=-1;ch=getchar();}
  9. while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=getchar();}
  10. return s*f;
  11. }//经典快读
  12. inline ll read_ll(){
  13. ll s=0;int f=1;char ch=getchar();
  14. while(ch<'0'||'9'<ch) {if(ch=='-') f=-1;ch=getchar();}
  15. while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=getchar();}
  16. return s*f;
  17. }//快读long long版
  18. inline void write(int x,char g){
  19. static char ch[30],top;
  20. top=0;if(x<0) {putchar('-');x=-x;}
  21. do{ch[++top]=x-x/10*10;} while(x/=10);
  22. do{putchar(ch[top--]+'0');} while(top);
  23. if(g!=0) putchar(g);
  24. }//经典快写
  25. inline void write_st(short x,char g){
  26. static char ch[30],top;
  27. top=0;if(x<0) {putchar('-');x=-x;}
  28. do{ch[++top]=x-x/10*10;} while(x/=10);
  29. do{putchar(ch[top--]+'0');} while(top);
  30. if(g!=0) putchar(g);
  31. }//快写short版
  32. int mt[12+3]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  33. int yt[2+3]={365,366};
  34. inline bool isR(int x){
  35. if(x<0) return !((x+1)%4);
  36. if(x<=1582) return !(x%4);
  37. return ((!(x%4) and x%100) or !(x%400) );
  38. }//判断是否为闰年
  39. inline short adm(short x,int y){
  40. if(y!=1582) return 0;
  41. if(x==10) return -10;
  42. return 0;
  43. }//用来处理1582
  44. inline short ady(int x){
  45. if(x==1582) return -10;
  46. return 0;
  47. }//同上
  48. struct ques{
  49. int id;ll x;
  50. inline friend bool operator<(ques x,ques y){
  51. return x.x<y.x;
  52. }
  53. }q[(int)1e5+3];
  54. int ay[(int)1e5+3];short am[(int)1e5+3],ad[(int)1e5+3];
  55. int ckt1;
  56. inline void ck1() {ckt1=clock();}
  57. inline void ck2() {printf("%dms\n",clock()-ckt1);}
  58. //这个是测速用的,可以忽略
  59. int main(){
  60. //filein(a);fileot(a);
  61. int Q=read();
  62. for(int i=1;i<=Q;++i){
  63. q[i].x=read_ll();
  64. q[i].id=i;
  65. }
  66. sort(q+1,q+1+Q);//操作离线
  67. for(int ss=1;ss<=Q;++ss){
  68. ll x=q[ss].x;
  69. int y=-4713;short m=1,d=1;
  70. if(ss!=1){//这个就是转换了
  71. x-=q[ss-1].x;
  72. y=ay[q[ss-1].id];
  73. m=am[q[ss-1].id];
  74. d=ad[q[ss-1].id];
  75. //printf("%d %d %d %d\n",q[ss-1].id,d,m,y);
  76. if(m!=1){
  77. if(d!=1){
  78. short kb=0;
  79. if(d<5 and y==1582 and m==10){
  80. kb+=10;
  81. }//越过空的日期
  82. if(x+kb>=mt[m]+((m==2)?isR(y):0)-d+1){
  83. x+=kb;
  84. x-=mt[m]+((m==2)?isR(y):0)-d+1;
  85. d=1;++m;
  86. if(m>12){
  87. m-=12;
  88. ++y;
  89. if(y==0) y=1;
  90. }
  91. if(m!=1){
  92. bool flag=0;
  93. for(short i=m;i<=12;++i){
  94. if(x>=mt[i]+((i==2)?isR(y):0+adm(i,y) ) ){
  95. x-=mt[i]+((i==2)?isR(y):0+adm(i,y) );
  96. }else{
  97. d+=x;
  98. if(d-x<=4 and d>4 and y==1582 and m==10){
  99. d+=10;
  100. }//这边越过空的日期花费了能量,补回来,下面的重复操作同理
  101. ay[q[ss].id]=y;
  102. am[q[ss].id]=i;
  103. ad[q[ss].id]=d;
  104. flag=1;break;//发现在转换的过程中就找到答案了,就结束操作,下面的重复操作同理
  105. }
  106. }
  107. if(flag) {continue;}
  108. m=1;++y;
  109. if(y==0) y=1;
  110. }
  111. }else{
  112. d+=x;
  113. if(d-x<=4 and d>4 and y==1582 and m==10){
  114. d+=10;
  115. }
  116. ay[q[ss].id]=y;
  117. am[q[ss].id]=m;
  118. ad[q[ss].id]=d;
  119. continue;
  120. }
  121. }else{
  122. bool flag=0;
  123. for(short i=m;i<=12;++i){
  124. if(x>=mt[i]+((i==2)?isR(y):0+adm(i,y) ) ){
  125. x-=mt[i]+((i==2)?isR(y):0+adm(i,y) );
  126. }else{
  127. d+=x;
  128. if(d-x<=4 and d>4 and y==1582 and m==10){
  129. d+=10;
  130. }
  131. ay[q[ss].id]=y;
  132. am[q[ss].id]=i;
  133. ad[q[ss].id]=d;
  134. flag=1;break;
  135. }
  136. }
  137. if(flag){continue;}
  138. m=1;++y;
  139. if(y==0) y=1;
  140. }
  141. }else if(d!=1){
  142. short kb=0;
  143. if(d<5 and y==1582 and m==10){
  144. kb+=10;
  145. }
  146. if(x+kb>=mt[m]-d+1){
  147. x+=kb;
  148. x-=mt[m]-d+1;
  149. d=1;++m;
  150. bool flag=0;
  151. for(short i=m;i<=12;++i){
  152. if(x>=mt[i]+((i==2)?isR(y):0+adm(i,y) ) ){
  153. x-=mt[i]+((i==2)?isR(y):0+adm(i,y) );
  154. }else{
  155. d+=x;
  156. if(d-x<=4 and d>4 and y==1582 and m==10){
  157. d+=10;
  158. }
  159. ay[q[ss].id]=y;
  160. am[q[ss].id]=i;
  161. ad[q[ss].id]=d;
  162. flag=1;break;
  163. }
  164. }
  165. if(flag) {continue;}
  166. m=1;++y;
  167. if(y==0) y=1;
  168. }else{
  169. d+=x;
  170. if(d-x<=4 and d>4 and y==1582 and m==10){
  171. d+=10;
  172. }
  173. ay[q[ss].id]=y;
  174. am[q[ss].id]=m;
  175. ad[q[ss].id]=d;
  176. continue;
  177. }
  178. }
  179. }
  180. //printf(" %d %d %d %d\n",d,m,y,x);
  181. bool Type=0;
  182. if(y>1582)
  183. while(x>=146100){
  184. x-=146097;
  185. y+=400;
  186. }
  187. while(x>=yt[Type=isR(y)]+ady(y) ){
  188. x-=yt[Type]+ady(y);
  189. ++y;
  190. if(y==0) y=1;
  191. }
  192. Type=isR(y);
  193. while(x>=(mt[m]+((m==2)?Type:0+adm(m,y)) ) ){
  194. x-=mt[m]+((m==2)?Type:0)+adm(m,y);
  195. ++m;
  196. }
  197. d+=x;
  198. if(d-x<=4 and d>4 and y==1582 and m==10){
  199. d+=10;
  200. }
  201. ay[q[ss].id]=y;
  202. am[q[ss].id]=m;
  203. ad[q[ss].id]=d;
  204. }
  205. for(int i=1;i<=Q;++i){
  206. int y=ay[i];short m=am[i],d=ad[i];
  207. if(y<0){
  208. write_st(d,' ');write_st(m,' ');write(-y,' ');
  209. printf("BC\n");
  210. }else{
  211. write_st(d,' ');write_st(m,' ');write(y,'\n');
  212. }
  213. }//输出
  214. return 0;
  215. }

题解 P7075 [CSP-S2020] 儒略日的更多相关文章

  1. 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解

    前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...

  2. [CSP模拟测试43、44]题解

    状态极差的两场.感觉现在自己的思维方式很是有问题. (但愿今天考试开始的一刻我不会看到H I J) A 考场上打了最短路+贪心,水了60. 然而正解其实比那30分贪心好想多了. 进行n次乘法后的结果一 ...

  3. 题解 nflsoj489 【六校联合训练 CSP #15】小D与随机

    题目链接 考虑枚举好点的集合.此时要考虑的问题是如何填入\(1\sim n\)这些数使得恰好我们枚举到的这些点是好点,即:求出有多少种合法的填数方案. \(1\)号点一定是好点.那么除\(1\)号点外 ...

  4. CCF CSP 201703-3 Markdown

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-3 Markdown 问题描述 Markdown 是一种很流行的轻量级标记语言(l ...

  5. CCF计算机职业资格认证考试题解

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF计算机职业资格认证考试题解 CCF计算机软件能力认证(简称CCF CSP认证)是CCF计算机职业资格认证系 ...

  6. CCF CSP 201312-3 最大的矩形

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-3 最大的矩形 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i( ...

  7. CCF CSP 201609-3 炉石传说

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201609-3 炉石传说 问题描述 <炉石传说:魔兽英雄传>(Hearthston ...

  8. CCF CSP 201403-3 命令行选项

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-3 命令行选项 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些 ...

  9. CCF CSP 201709-4 通信网络

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201709-4 通信网络 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M ...

随机推荐

  1. CSS:两端对齐原理(text-align:justify)

    我是一个小白我是一个小白我是一个小白喷我吧,哈哈 写样式的是时候经常会碰到字体两端对齐的效果,一般就网上找端css样式复制下就结束了,没有考虑过原理是啥贴下代码 <head> <me ...

  2. C#ASP.NET网站开发步骤

    1. 创建项目ASP.NET Web 应用程序. 2. 选择"Web 窗体"模板,然后单击 "确定" 按钮创建项目. 3. 在解决方案资源管理器中,右键添加we ...

  3. java中求一下2008年5月31日, 往前倒30天是哪天?

    题目9: 2008年5月31日, 往前倒30天是哪天?  import java.util.*; public class Test {     public static void main(Str ...

  4. 解决vue安装时出现vue --version或vue不是内部命令的问题

    1. 试图全局配置 vue 的环境变量,找到 vue.cmd 的路径,然后进行配置. 问题:在文件搜索中,没有找到 vue.cmd,失败. 1.npm i npm -g 全局 update 了 npm ...

  5. MFC软件国际化的几个问题及其解决方案

    作者:马健 邮箱:stronghorse_mj@hotmail.com主页:https://www.cnblogs.com/stronghorse/ 以前我以为PDG相关软件只会在国内流行,所以发行简 ...

  6. 小程序容器助力打造企业超级App

    阿拉丁研究院发布<2021 年度小程序互联网发展白皮书>显示,2021 年全网小程序数量已超 700 万,其中微信小程序开发者突破 300 万,DAU 超过 4.5 亿:日均使用次数同比增 ...

  7. metasploit基本命令

    一.核心命令 ? 帮助命令 banner 显示一个真棒metasploite横幅 cd 更改当前的工作目 color 切换颜色 connect 连接与主机通信 exit 退出控制台 get 获取特定于 ...

  8. Java三大结构

    Java三大结构 顺序结构(基本结构) 选择结构 循环结构 1. 顺序结构 平时一般语句都默认遵循顺序结构 2. 选择结构 2.1 if单选择结构 语法 if(布尔表达式){ //布尔表达式为true ...

  9. Edu Cf Round 105 (Div. 2) B. Berland Crossword 1.读懂题, 2. 思维

    一. 原题链接 https://codeforces.com/contest/1494/problem/B   二. 题意 + 题解: 没看懂题目, 懵了好久, 先狡辩一下当时误解的句子, 英语是硬伤 ...

  10. thinkphp6事件监听event-listene

    事件系统可以看成是行为系统的升级版,相比行为系统强大的地方在于事件本身可以是一个类,并且可以更好的支持事件订阅者. 事件相比较中间件的优势是事件比中间件更加精准定位(或者说粒度更细),并且更适合一些业 ...