儒略日大样例对错都有

题目链接:https://www.luogu.com.cn/problem/P7075
调了挺久了。小一点的数字能对的,大样例对错都有,错的一般是多了一天。给代码注释了一下。

错误样例

1

543525290

正确答案为

7 8 1483409

我的答案:

8 8 1483409

前两个样例是能过的。所以我怀疑我的代码前一部分出了问题。即1582 年 10 月 4日以后有问题。

代码丑陋。

#include
using namespace std;
#define rt register int 
int T,newy,newm,newd;
long long n;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int month2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main(){
//    freopen("julian3.in","r",stdin);
//    freopen("julian3.out","w",stdout); 
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        cin>>n;
        if(n==2299160)cout<<4<<" "<<10<<" "<<1582<//以此为时间点 ,一共有2299160天 
        else if(n>2299160){
            newy=1582,newm=10,newd=1;n+=13;//补上不存在的天数 
            n-=2299160;//扣掉初始化用掉的天数 
            while(1){//到第几年 
                if((newy%4==0&&newy%100!=0)||newy%400==0){//闰年判断 
                    if(n>=366){
                        ++newy;n-=366;
                    }else break;//如果不够减就退出年的计算 
                }else{
                    if(n>=365){
                        ++newy;n-=365;
                    }else break;
                }
            }
            while(1){//这里是决定到第几月份 
                if((newy%4==0&&newy%100!=0)||newy%400==0)
                {
                    if(n>=month2[newm]){//month2对应闰年 
                        n-=month2[newm];++newm;
                        if(newm>12){++newy;newm=1;}//防止月份溢出 
                    }else break;//进入日的计算 
                }else{
                    if(n>=month[newm]){
                        n-=month[newm];++newm;
                        if(newm>12){++newy;newm=1;}
                    }else break;
                }
            }
                if((newy%4==0&&newy%100!=0)||newy%400==0){//计算天数 
                    newd+=n;
                    if(newd>month2[newm]){
                        newd-=month2[newm];
                        ++newm;
                        if(newm>12){++newy;newm=1;}//防溢出 
                    }
                }else{
                    newd+=n;
                    if(newd>month[newm]){
                        newd-=month[newm];
                        ++newm;
                        if(newm>12){++newy;newm=1;}
                    }
                }
        }else{
            newy=-4713,newm=1,newd=1;
            while(1){
                if((newy<0&&(-newy-1)%4==0)||newy>0&&newy%4==0){
                    if(n>=366){
                        ++newy;n-=366;
                        if(newy==0)++newy;
                    }else break;
                }else{
                    if(n>=365){
                        ++newy;n-=365;
                        if(newy==0)++newy;
                    }else break;
                }
            }
            while(1){
                if((newy<0&&(-newy-1)%4==0)||newy>0&&newy%4==0)
                {
                    if(n>=month2[newm]){
                        n-=month2[newm];++newm;
                        if(newm>12){++newy;newm=1;if(newy==0)++newy;}
                    }else break;
                }else{
                    if(n>=month[newm]){
                        n-=month[newm];++newm;
                        if(newm>12){++newy;newm=1;if(newy==0)++newy;}
                    }else break;
                }
            }
                if((newy<0&&(-newy-1)%4==0)||newy>0&&newy%4==0){
                    newd+=n;
                    if(newd>month2[newm]){
                        newd-=month2[newm];
                        ++newm;
                        if(newm>12){++newy;newm=1;if(newy==0)++newy;}
                    }
                }else{
                    newd+=n;
                    if(newd>month[newm]){
                        newd-=month[newm];
                        ++newm;
                        if(newm>12){++newy;newm=1;if(newy==0)++newy;}
                    }
                }
        }
        if(newy>0)
            cout<<newd<<" "<<newm<<" "<<newy<else 
            cout<<newd<<" "<<newm<<" "<<-newy<<" "<<"BC"<

80pts:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
//#pragma GCC optimized(2)
using namespace std;
const int Q = 100010;

int read() {
    int re = 0;
    char c = getchar();
    bool negt = false;
    while(c < '0' || c > '9')
        negt |= (c == '-') , c = getchar();
    while(c >= '0' && c <= '9')
        re = c - '0' + (re << 1) + (re << 3) , c = getchar();
    return negt ? -re : re;
}

const int mon[2][15] = {
    {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 {
    int y , d , m;//year date month. y<0表示公元前
};
inline date next(date d) {
    if(d.y == 1582 && d.m == 10 && d.d == 4){
        d.d = 15;
        return d;
    }
    
    bool run;
    if(d.y < 0)
        run = ((-d.y - 1) % 4 == 0);
    else if(d.y <= 1582)
        run = (d.y % 4 == 0);
    else
        run = (d.y % 4 == 0 && d.y % 100 != 0 || d.y % 400 == 0);
        
    ++d.d;
    if(d.d > mon[run][d.m])
        ++d.m , d.d = 1;
    if(d.m > 12)
        ++d.y , d.m = 1;
    if(d.y == 0)
        d.y = 1;
    return d;
}

struct query {
    int r , id;
} q[Q];
bool cmp(query a , query b) {
    return a.r < b.r;
}
int qnum;
date ans[Q];
signed main() {
    qnum = read();
    for(int i = 1 ; i <= qnum ; i++)
        q[i].r = read() , q[i].id = i;

    sort(q + 1 , q + qnum + 1 , cmp);

    int cnt = 0;
    date d;
    d.y = -4713 , d.m = 1 , d.d = 1;
    for(int i = 1 ; i <= qnum ; i++) {
        while(cnt < q[i].r)
            ++cnt , d = next(d);
        ans[q[i].id] = d;
    }

    for(int i = 1 ; i <= qnum ; i++) {
        if(ans[i].y < 0) {
            printf("%d %d %d BC\n" , ans[i].d , ans[i].m , -ans[i].y);
        } else {
            printf("%d %d %d\n" , ans[i].d , ans[i].m , ans[i].y);
        }
    }
    return 0;
}


100pts


#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
//#pragma GCC optimized(2)
using namespace std;
const int Q = 100010;
const int DayOf400Y = 365 * 400 + 97;
const int LogR = 30;

int read() {
    int re = 0;
    char c = getchar();
    bool negt = false;
    while(c < '0' || c > '9')
        negt |= (c == '-') , c = getchar();
    while(c >= '0' && c <= '9')
        re = c - '0' + (re << 1) + (re << 3) , c = getchar();
    return negt ? -re : re;
}

const int mon[2][15] = {
    {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 {
    int y , d , m;
};
inline date next(date d) {
    if(d.y == 1582 && d.m == 10 && d.d == 4){
        d.d = 15;
        return d;
    }
    
    bool run;
    if(d.y < 0)
        run = ((-d.y - 1) % 4 == 0);
    else if(d.y <= 1582)
        run = (d.y % 4 == 0);
    else
        run = (d.y % 4 == 0 && d.y % 100 != 0 || d.y % 400 == 0);
        
    ++d.d;
    if(d.d > mon[run][d.m])
        ++d.m , d.d = 1;
    if(d.m > 12)
        ++d.y , d.m = 1;
    if(d.y == 0)
        d.y = 1;
    return d;
}

struct query {
    int r , id;
} q[Q];
bool cmp(query a , query b) {
    return a.r < b.r;
}
int qnum;
date ans[Q];
signed main() {
    qnum = read();
    for(int i = 1 ; i <= qnum ; i++)
        q[i].r = read() , q[i].id = i;

    sort(q + 1 , q + qnum + 1 , cmp);

    int cnt = 0;
    date d;
    d.y = -4713 , d.m = 1 , d.d = 1;
    
    int i;
    for(i = 1 ; d.y < 2000 && i <= qnum ;) {
        while(cnt < q[i].r && d.y < 2000)
            ++cnt , d = next(d);
        if(d.y < 2000)
            ans[q[i].id] = d , ++i;
    }
    //此时d=202011日,cnt为这天的儒略日
    int cnt_;//当前儒略日
    date d1;//当前格里高利历日期
    for( ; i <= qnum ; i++) {
        cnt_ = cnt , d1 = d;//从时间基线开始
        
        for(int j = LogR ; j >= 0 ; j--)//400年*2^j 倍增
            if(cnt_ + (DayOf400Y << j) <= q[i].r)
                cnt_ += (DayOf400Y << j) , d1.y += (400ll << j);
        
        while(cnt_ + 366 <= q[i].r) {//年份逼近
            if(d1.y % 4 == 0 && d1.y % 100 != 0 || d1.y % 400 == 0)
                cnt_ += 366;
            else
                cnt_ += 365;
            d1.y += 1;
        }
        while(cnt_ < q[i].r)//日期逼近
            ++cnt_ , d1 = next(d1);
        ans[q[i].id] = d1;
    }

    for(int i = 1 ; i <= qnum ; i++) {
        if(ans[i].y < 0) {
            printf("%d %d %d BC\n" , ans[i].d , ans[i].m , -ans[i].y);
        } else {
            printf("%d %d %d\n" , ans[i].d , ans[i].m , ans[i].y);
        }
    }
    return 0;
}