zoukankan      html  css  js  c++  java
  • 【CSP2020】 T1儒略日

    NOIPCSP2020终于结束辣,可是这跟我一个大一学生有什么关系呢?,作为曾经的OI狗,也作为准备冲击ACM校队的一名蒟蒻,我决定做一做今年的题。

    题目链接
    https://www.luogu.com.cn/problem/P7075?contestId=37022

    本题是一道显然的大模拟,思路很简单,但是需要考虑的细节实在是太多力QwQ,窝写了4个多小时才A掉此题(想必如果真在赛场就要喜提省四了罢),最终发现少写了一个return。。。

    简单讲一下一些优化技巧吧,首先,可以写一个函数计算每年的第几天是几月几日,减少大量重复操作。而且,接下来只要考虑年份和天数,去除了干扰因素。同时,利用题目信息,将问题分段。对于格里高利历,有400和100对闰年的影响,可以将1582年到1599年单独分一组,这样,从1600年1月1日开始,就可以400年一个周期,变得有规律了。

    代码

    #include<cstdlib>
    #define ll long long
    using namespace std;
    int d[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,
    0,31,29,31,30,31,30,31,31,30,31,30,31
    };
    struct date{
    	bool BC;
    	int month,day;
    	ll year;
    };
    date f(int x,int flag,int isBC){
    	int i;
    	date ans;
    	ans.BC=isBC;
    	for(i=1;i<=12;i++){
    		if(x<=d[flag][i]){
    			ans.month=i;ans.day=x;
    			return ans;
    		}
    		x-=d[flag][i];
    	}
    }
    date julian(ll x){
    	date ans;
    	int tmp=4713*365+4712/4+1;
    	if(x<=tmp){//BC
    		ll t=(x-1)/(4*365+1);
    		ll r=x-t*(4*365+1);
    		ll y=4713-t*4;
    		if(r>366){
    			y--;r-=366;
    		}
    		else{
    			ans=f(r,1,1);
    			ans.year=y;
    			return ans;
    		}
    		if(r>365){
    			y--;r-=365;
    		}
    		else{
    			ans=f(r,0,1);
    			ans.year=y;
    			return ans;
    		}
    		if(r>365){
    			y--;r-=365;
    		}
    		else{
    			ans=f(r,0,1);
    			ans.year=y;
    			return ans;
    		}
    		ans=f(r,0,1);
    		ans.year=y;
    		return ans;
    	}
    	else{//AD
    		x-=tmp;
    		tmp=1581*365+1582/4+277;
    		if(x<=tmp){//julian
    			ll t=(x-1)/(4*365+1);
    			ll r=x-t*(4*365+1);
    			ll y=4*t+1;
    			if(r>365){
    				y++;r-=365;
    			}
    			else{
    				ans=f(r,0,0);
    				ans.year=y;
    				return ans;
    			}
    			if(r>365){
    				y++;r-=365;
    			}
    			else{
    				ans=f(r,0,0);
    				ans.year=y;
    				return ans;
    			}
    			if(r>365){
    				y++;r-=365;
    			}
    			else{
    				ans=f(r,0,0);
    				ans.year=y;
    				return ans;
    			}
    			ans=f(r,1,0);
    			ans.year=y;
    			return ans;
    		}
    		else{//new
    			x+=10-tmp;
    			if(x<=88+(1600-1583)*365+4){//before 1600 1 1
    				if(x<=88){//this year
    					ans=f(x+277,0,0);
    					ans.year=1582;
    					return ans;
    				}
    				else{
    					x-=88;
    					for(int i=1583;i<1600;i++){
    						int kkk;
    						if(!(i%4)) kkk=1;
    						else kkk=0;
    						if(x<=365+kkk){
    							ans=f(x,kkk,0);
    							ans.year=i;
    							return ans;
    						}
    						x-=365+kkk;
    					}
    				}
    			}
    			else{//after 1600 1 1
    				x-=88+(1600-1583)*365+4;
    				ll t=(x-1)/(400*365+100-4+1);
    				ll y=1600+t*400;
    				x-=t*(400*365+100-4+1);
    				if(x<=100*365+25){
    					ll tt=(x-1)/(4*365+1);
    					ll r=x-tt*(4*365+1);
    					y+=tt*4;
    					if(r>366){
    						y++;r-=366;
    					}
    					else{
    						ans=f(r,1,0);
    						ans.year=y;
    						return ans;
    					}
    					if(r>365){
    						y++;r-=365;
    					}
    					else{
    						ans=f(r,0,0);
    						ans.year=y;
    						return ans;
    					}
    					if(r>365){
    						y++;r-=365;
    					}
    					else{
    						ans=f(r,0,0);
    						ans.year=y;
    						return ans;
    					}
    					ans=f(r,0,0);
    					ans.year=y;
    					return ans;
    				}
    				else{
    					x-=(100*365+25);
    					y+=100;
    					ll tt=(x-1)/(100*365+25-1);
    					ll r=x-tt*(100*365+25-1);
    					y+=tt*100;
    					if(r>31+28) r++;
    					tt=(r-1)/(4*365+1);
    					r=r-tt*(4*365+1);
    					y+=tt*4;
    					if(r>366){
    						y++;r-=366;
    					}
    					else{
    						ans=f(r,1,0);
    						ans.year=y;
    						return ans;
    					}
    					if(r>365){
    						y++;r-=365;
    					}
    					else{
    						ans=f(r,0,0);
    						ans.year=y;
    						return ans;
    					}
    					if(r>365){
    						y++;r-=365;
    					}
    					else{
    						ans=f(r,0,0);
    						ans.year=y;
    						return ans;
    					}
    					ans=f(r,0,0);
    					ans.year=y;
    					return ans;
    				}
    			}
    		}
    	}
    }
    int main(){
    	int T,i,j;
    	ll x;
    	date ans;
    	// freopen("julian3.in","r",stdin);
    	// freopen("out.txt","w",stdout);
    	scanf("%d",&T);
    	for(i=1;i<=T;i++){
    		scanf("%lld",&x);
    		ans=julian(x+1);
    		printf("%d %d %lld",ans.day,ans.month,ans.year);
    		if(ans.BC) printf(" BC");
    		printf("
    ");
    	}
    	return 0;
    }
  • 相关阅读:
    SDN实验 7: OpenDaylight 实验——Python 中的 REST API 调用
    2020软工第四次作业:结对编程作业
    SDN实验 6: OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
    SDN实验 5: OpenFlow 协议分析和 OpenDaylight 安装
    SDN实验 4: Open vSwitch 实验——Mininet 中使用 OVS 命令
    2020软工第二次作业
    SDN实验3:Mininet 实验——测量路径的损耗率
    软件工程实践个人总结
    软件工程实践番外篇——获小黄衫有感
    软件定义网络实验 7:OpenDaylight 实验——Python 中的 REST API 调用(含选做题)
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/13956042.html
Copyright © 2011-2022 走看看