• P7075 儒略日(2020CSP-S T1)


    考试的时候就一个地方写挂了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊,要不然就完成了场切大模拟的壮举

    思路

    有什么思路啊,就模拟啊。。。首先发现1582年之前是白给,我一开始决定整个题都使用取模操作。但是我发现公元前4713年1月1日是第0天,也就是这一天不算在儒略日内,但是公元1年1月1日是算的,这就导致它们之间的代码有很多细节都不一样,我也就是这里写挂了。其实公元前取模操作比较好写,好吧其实差不多的,但我考场上就是取模取挂了,本来应该是1111年12月31号,我取模一个细节炸了,输出了1115年12月31号。痛失60pts。但是无所谓,毕竟这次考试并不重要。所以我改成公元后一年一年地跑,就算全是极限数据,也才是1e8(我相信i7的实力),是可以跑的,况且出题人不可能构造这样的数据,那1e5组不可能都是1582年之前的,显然1582年之后更恶心。这样暴力跑完之后,1582年之后必须取模了,不然复杂度炸裂。注意到闰年是400年一个周期,也就是说我们可以算出400年一共多少天,然后对它取模,就可以将年份确定在400年的一个区间里,在这个区间内再一年一年跑,时间复杂度最差是(O(400Q)),对i7来说小菜一碟,而且不可能这么精准地卡到我最差时间复杂度。当然,为了便于实现,我特判了1582年到1582年之间的部分,从1583年1月1日开始算,会更加方便。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<ctime>
    #include<map>
    using namespace std;
    typedef long long ll;
    inline ll read(){
    	ll x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    ll Q,r,ri,yue,nian;
    ll run[15]={0,31,29,31,30,31,30,31,31,30,31,30,31};
    ll ping[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int main()
    {
    	Q=read();
    	while(Q--){
    		r=read();
    		if(r<=1721423){//公元前
    			ll sum1=r/1461,sum2=r%1461+1;
    			nian=4713-sum1*4;//取模操作,细节手玩即可
    			for(ll i=nian;i;i--){
    				if(nian%4==1){
    					if(sum2<=366){
    						break;
    					}
    					else{
    						sum2-=366;
    						nian--;
    					}
    				}
    				else{
    					if(sum2<=365){
    						break;
    					}
    					else{
    						sum2-=365;
    						nian--;
    					}
    				}
    			}
    			if(nian%4==1){
    				for(ll i=1;i<=12;i++){
    					if(sum2<=run[i]){
    						yue=i;
    						ri=sum2;
    						break;
    					}
    					else{
    						sum2-=run[i];
    					}
    				}
    			}
    			else{
    				for(ll i=1;i<=12;i++){
    					if(sum2<=ping[i]){
    						yue=i;
    						ri=sum2;
    						break;
    					}
    					else{
    						sum2-=ping[i];
    					}
    				}
    			}//确定区间后一年一年跑
    			printf("%lld %lld %lld BC
    ",ri,yue,nian);
    			continue;
    		} 
    		else{
    			r-=1721423;//减去公元前的天数
    			if(r<=577737){//1582年之前
    				nian=1;
    				ll sum2=r;
    				for(int i=nian;i;i++){//直接暴力枚举
    					if(i%4==0){
    						if(sum2<=366){
    							break;
    						}
    						else{
    							sum2-=366;
    							nian++;
    						}
    					}
    					else{
    						if(sum2<=365){
    							break;
    						}
    						else{
    							sum2-=365;
    							nian++;
    						}	
    					}
    				}
    				if(nian%4==0){
    					for(int i=1;i<=12;i++){
    						if(sum2<=run[i]){
    							yue=i;
    							ri=sum2;
    							break;
    						}
    						else{
    							sum2-=run[i];
    						}
    					}
    				}
    				else{
    					for(int i=1;i<=12;i++){
    						if(sum2<=ping[i]){
    							yue=i;
    							ri=sum2;
    							break;
    						}
    						else{
    							sum2-=ping[i];
    						}
    					}
    				}
    				printf("%lld %lld %lld
    ",ri,yue,nian);
    			}
    			else{//1582年之后
    				r-=577737;
    				nian=1582;
    				if(r<=78){
    					if(r<=78&&r>47){
    						ri=r-47;
    						yue=12;
    					}
    					if(r<=47&&r>17){
    						ri=r-17;
    						yue=11;
    					}
    					if(r<=17&&r>0){
    						ri=r+14;
    						yue=10;
    					}
    					printf("%lld %lld %lld
    ",ri,yue,nian);
    					continue;
    				}//特判到1583年
    				nian=1583;
    				r-=78;
    				ll sum1=r/146097,sum2=r%146097;
    				nian+=sum1*400;
    				if(sum2==0){
    					nian--;
    					sum2=146097;
    				}
    				for(ll i=nian;i;i++){
    					if(nian%4==0){
    						if(nian%100!=0||nian%400==0){
    							if(sum2<=366){
    								break;
    							}
    							else{
    								sum2-=366;
    								nian++;
    							}
    						} 
    						else{
    							if(sum2<=365){
    								break;
    							}
    							else{
    								sum2-=365;
    								nian++;
    							}
    						}
    					}
    					else{
    						if(sum2<=365){
    							break;
    						}
    						else{
    							sum2-=365;
    							nian++;
    						}
    					}
    				}
    				if(nian%4==0){
    					if((nian%100!=0)||(nian%400==0)){
    						for(ll i=1;i<=12;i++){
    							if(sum2<=run[i]){
    								yue=i;
    								ri=sum2;
    								break;
    							}
    							else{
    								sum2-=run[i];
    							}
    						}
    					} 
    					else{
    						for(ll i=1;i<=12;i++){
    							if(sum2<=ping[i]){
    								yue=i;
    								ri=sum2;
    								break;
    							}
    							else{
    								sum2-=ping[i];
    							}
    						}
    					}
    				}
    				else{
    					for(ll i=1;i<=12;i++){
    						if(sum2<=ping[i]){
    							yue=i;
    							ri=sum2;
    							break;
    						}
    						else{
    							sum2-=ping[i];
    						}
    					}
    				}
    				printf("%lld %lld %lld
    ",ri,yue,nian);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    config Doku wiki
    [转载]【python】ipython与python的区别
    数组和指针
    C++初始化数据成员
    RSA算法原理
    C++四种cast
    百度笔试准备2
    百度笔试准备1
    百度面试准备
    C++的空类中默认产生哪些类成员函数
  • 原文地址:https://www.cnblogs.com/57xmz/p/13959762.html
Copyright © 2020-2023  润新知