题目链接: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=2020年1月1日,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;
}