由于会有好多题中涉及到两个日期之间天数的计算,所以找到一个好用模板;输入开始的年,月,日到结束的年,月,日;
#include <bits/stdc++.h>
using namespace std;
int day(int year,int month,int day)//到0年3月1日的天数
{
int m=(month+9)%12,y=year-m/10;
return 365*y+y/4-y/100+y/400+(m*306+5)/10+(day-1);
}
int main()
{
int sy,sm,sd,ey,em,ed;
while(~scanf("%d%d%d%d%d%d",&sy,&sm,&sd,&ey,&em,&ed))
{
printf("%d\n",day(ey,em,ed)-day(sy,sm,sd));
}
return 0;
}
该算法总体思想是计算给定日期到 0年3月1日的天数,然后相减,获取天数的间隔。
m = (month + 9) % 12; 用于判断日期是否大于3月(2月是判断闰年的标识),还用于纪录到3月的间隔月数。
y = year - m/10; 如果是1月和2月,则不包括当前年(因为是计算到0年3月1日的天数)。
365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + (day- 1);
其中 365*y1 是不算闰年多出那一天的天数,
y/4 - y/100 + y/400 是加所有闰年多出的那一天(容斥原理),
(m*306 + 5)/10 用于计算到当前月到3月1日间的天数,306=365-31-28(1月和2月),5是全年中不是31天月份的个数
(day - 1) 用于计算当前日到1日的间隔天数。
下面给两道题可以去练练;
#include <bits/stdc++.h>
using namespace std;
int day(int year,int month,int day)
{
int m=(month+9)%12,y=year-m/10;
return 365*y+y/4-y/100+y/400+(m*306+5)/10+(day-1);
}
int main()
{
int T,sy,sm,sd;cin>>T;
while(T--)
{
scanf("%d-%d-%d",&sy,&sm,&sd);
if((sy%4==0||sy%400==0)&&sm==2&&sd==29)
{
printf("-1\n");
}
else
{
printf("%d\n",day(sy+18,sm,sd)-day(sy,sm,sd));
}
}
return 0;
}
HUSTOJ-2344-求日龄
#include <bits/stdc++.h>
using namespace std;
int day(int year,int month,int day)
{
int m=(month+9)%12,y=year-m/10;
return 365*y+y/4-y/100+y/400+(m*306+5)/10+(day-1);
}
int main()
{
int sy,sm,sd,ey,em,ed;
while(~scanf("%d-%d-%d",&sy,&sm,&sd))
{
printf("%d\n",day(2013,3,9)-day(sy,sm,sd));
}
return 0;
}