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;
    }
  • 相关阅读:
    http强转https websocket
    apache http添加证书转成https
    insert into
    分割字符串和截取字符串:split 和substring
    java实现http请求
    Oracle 中 decode 函数用法
    LeetCode:154. 寻找旋转排序数组中的最小值 II
    LeetCode:153. 寻找旋转排序数组中的最小值
    LeetCode:151. 翻转字符串里的单词
    LeetCode:145. 二叉树的后序遍历
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/13956042.html
Copyright © 2011-2022 走看看