在学习算法程序设计中,总结几个日期计算的函数。这类问题对应于循环和数组的应用有益,也适合于分类讨论的简单学习。数学思想上相当于初中水平,所以也称之为入门。
口诀:==四年一闰则百年不闰,四百年一闰==
bool IsLeap(int n){
return (n%4==0 && n%100!=0 ||n%400==0);
}
bool类型表示判断真假,后面返回值可以是一个判断式子,相当于if中的返回0,1。同样,bool返回值也可以用于数组下标表示
算法:循环模拟求和即可
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int Date(int y,int m,int d){
if(IsLeap(y)) month[2]=29;
else month[2]=28;
int sum=0;
for(int i=1;i<=m;i++){
if(i==m){
sum+=d;
}else{
sum+=month[i];
}
}
return sum;
}
算法:循环遍历和分类讨论
当日期同年同月,直接日期相减;
当日期同年不同月,则用前面函数计算该日期是该年第几天,两者相减;
当日期不同年,则分成三部分求和:==小年年末差+间隔整年天数+大年第几天天数==
int DateBetw(int y1,int m1,int d1,int y2,int m2,int d2){
int sum=0;
if(y1==y2 && m1==m2){
sum=d2-d1;
}else if(y1==y2){
//前面计算日期为该年第几天
sum=Date(y2,m2,d2)-Date(y1,m1,d1);
}else{
//小年年末
if(IsLeap(y1)) sum+=366-Date(y1,m1,d1);
else sum+=365-Date(y1,m1,d1);
//中间整年间隔
for(int i=y1+1;i
算法1:求出该日期和一个已知星期几的日期相差天数,该一直日期要早于题目日期,星期是7天一循环,一次用相差天数对7取余即可
算法2:和上述差不多,只是可以不用要求一直星期的日期早。==若已知星期日期晚于题目日期,差值取负数对7取余再加7即可==
小技巧:公元1年1月1号是星期一,不过一般不用;1900年1月1是星期一,1000年1月1是星期三,这些估计够用
计算星期几(题目链接)
#include
typedef long long ll;
using namespace std;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//判断闰年
bool Isleap(int y){
return (y%4==0 && y%100!=0 ||y%400==0);
}
//计算该日期是该年的第几天
int dates(int y,int m,int d){
if(Isleap(y)) month[2]=29;
else month[2]=28;
int sum=0;
for(int i=1;i
算法:和上面的题目很像,一九是要分类讨论和循环,难度不大,注意输出格式。
计算日期(题目链接)
#include
typedef long long ll;
using namespace std;
bool Isleap(int y){
return (y%4==0 && y%100!=0 ||y%400==0);
}
//求过多少天之后的日期
int main(){
int n;
cin>>n;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
while(n--){
int y,m,d,cnt;
cin>>y>>m>>d>>cnt;
while(cnt!=0){
int year;
//闰年
if(Isleap(y)){
year=366;month[2]=29;
}
else{
year=365;month[2]=28;
}
//增加
if(cnt>=year){
cnt-=year;
y++;
}else if(cnt>=month[m]){
cnt-=month[m];
m++;
if(m>12){
m-=12;
y++;
}
}else{
d+=cnt;
cnt=0;
if(d>month[m]){
d-=month[m];
m++;
if(m>12){
m-=12;
y++;
}
}
}
}
//计算日期函数
printf("%d-%02d-%02d\n",y,m,d);
}
return 0;
}