算法提高 日期计算
问题描述
已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢400年闰的情况。
输入格式
输入只有一行
YYYY MM DD
YYYY MM DD
输出格式
输出只有一行
W
W
数据规模和约定
1599 <= YYYY <= 2999
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
样例输入
2011 11 11
样例输出
5
#include <iostream>
using namespace std;
int pmon[13]={365,31,28,31,30,31,30,31,31,30,31,30,31};//平年月份天数表
int lmon[13]={366,31,29,31,30,31,30,31,31,30,31,30,31};//闰年月份天数表
int week[7]={5,6,7,1,2,3,4};//当日期晚于2011年11月11日时星期辅助数组
int rweek[7]={5,4,3,2,1,7,6};//当日期早于2011年11月11日时星期辅助数组
bool isleap(int year)//判断是否是闰年
{
if(year%100==0&&year%400!=0)
return false;
if(year%4==0)
return true;
return false;
}
int nday(int yy,int mm,int dd,int flag)//flag=1计算从yy年mm月dd日到这一年末有多少天,flag=0计算到本年初有多少天
{
int day;
if(flag==1)
{
day=isleap(yy)?lmon[mm]-dd:pmon[mm]-dd;//计算当月到月末天数
for(int i=mm+1;i<=12;i++)//计算从下个月到12月所有天数
day+=isleap(yy)?lmon[i]:pmon[i];
}
else
{
day=dd;//计算当月到月初天数
for(int i=mm-1;i>=1;i--)//计算从上个月到1月所有天数
day+=isleap(yy)?lmon[i]:pmon[i];
}
return day;
}
int nweek(int yy,int mm,int dd)//计算某个日期是周几函数
{
int weeky;
if(yy<2011)//当所求年分早于2011年11月11日时
{
/**比如求从2008年3月12日到2011年11月11日有几天,先求2011.11.11-2011.1.1有几天
再求 2009-2010年有几天,再求2008.3.12-2008.12.31有几天,最后把这三个数加起来**/
int day=nday(2011,11,11,0); //计算出2011年11月11日到2011年初天数
for(int i=2010;i>yy;i--) //计算出从2010年到所求年份后一年有几天
day+=(isleap(i)?lmon[0]:pmon[0]);
day+=nday(yy,mm,dd,1); //计算出所求日期到所求年份年初的
weeky=rweek[day%7]; //最后用辅助数组求出是周几
}
else if(yy>2011)//晚于2011年时道理相同
{
int day=nday(2011,11,11,1);
for(int i=2012;i<yy;i++)
day+=(isleap(i)?lmon[0]:pmon[0]);
day+=nday(yy,mm,dd,0);
weeky=week[day%7];
}
else//当年分等于2011年再把月份和年一样进行划分
{
int day=0;
if(mm>11)
{
day=dd+19;
weeky=week[day%7];
}
else if(mm<11)
{
day=11;
for(int i=10;i>mm;i--)
day+=(isleap(yy)?lmon[i]:pmon[i]);
day+=(isleap(yy)?lmon[mm]-dd:pmon[mm]-dd);
weeky=rweek[day%7];
}
else//当月份等于11月再将日期和年份一样进行划分
{
if(dd==11)
weeky=5;
else if(dd>11)
weeky=week[(dd-11)%7];
else
weeky=rweek[(11-dd)%7];
}
}
return weeky;
}
int main()
{
int yy,mm,dd;
cin>>yy>>mm>>dd;
cout<<nweek(yy,mm,dd)<<endl;
return 0;
}
又碰到算法提高一个题发现可以和这个题用一个辅助函数,说实话这种题太无聊
只要计算出这个月第一天是周几,然后顺着往后打印就可以
算法提高 5-3日历
问题描述
已知2007年1月1日为星期一。设计一函数按照下述格式打印2007年以后(含)某年某月的日历,2007年以前的拒绝打印。为完成此函数,设计必要的辅助函数也是必要的。
样例输入
一个满足题目要求的输入范例。
例:
2050 3
例:
2050 3
样例输出
与上面的样例输入对应的输出。
例:
例:
数据规模和约定
输入数据中每一个数的范围。
例:年 2007-3000,月:1-12。
例:年 2007-3000,月:1-12。
#include <iostream>
using namespace std;
int pmon[13]={365,31,28,31,30,31,30,31,31,30,31,30,31};
int lmon[13]={366,31,29,31,30,31,30,31,31,30,31,30,31};
int week[7]={5,6,7,1,2,3,4};
int rweek[7]={5,4,3,2,1,7,6};
bool isleap(int year)
{
if(year%100==0&&year%400!=0)
return false;
if(year%4==0)
return true;
return false;
}
int nday(int yy,int mm,int dd,int flag)
{
int day;
if(flag==1)
{
day=isleap(yy)?lmon[mm]-dd:pmon[mm]-dd;
for(int i=mm+1;i<=12;i++)
day+=isleap(yy)?lmon[i]:pmon[i];
}
else
{
day=dd;
for(int i=mm-1;i>=1;i--)
day+=isleap(yy)?lmon[i]:pmon[i];
}
return day;
}
int nweek(int yy,int mm,int dd)
{
int weeky;
if(yy<2011)
{
int day=nday(2011,11,11,0);
for(int i=2010;i>yy;i--)
day+=(isleap(i)?lmon[0]:pmon[0]);
day+=nday(yy,mm,dd,1);
weeky=rweek[day%7];
}
else if(yy>2011)
{
int day=nday(2011,11,11,1);
for(int i=2012;i<yy;i++)
day+=(isleap(i)?lmon[0]:pmon[0]);
day+=nday(yy,mm,dd,0);
weeky=week[day%7];
}
else
{
int day=0;
if(mm>11)
{
day=dd+19;
weeky=week[day%7];
}
else if(mm<11)
{
day=11;
for(int i=10;i>mm;i--)
day+=(isleap(yy)?lmon[i]:pmon[i]);
day+=(isleap(yy)?lmon[mm]-dd:pmon[mm]-dd);
weeky=rweek[day%7];
}
else
{
if(dd==11)
weeky=5;
else if(dd>11)
weeky=week[(dd-11)%7];
else
weeky=rweek[(11-dd)%7];
}
}
return weeky;
}
int main()
{
int yy,mm,ed,day[6][7]={{0}},k=1;
cin>>yy>>mm;
cout<<"Calendar "<<yy<<" - ";
if(mm<10)
cout<<"0"<<mm<<endl;
else
cout<<mm<<endl;
cout<<"---------------------"<<endl;
cout<<"Su Mo Tu We Th Fr Sa"<<endl;
cout<<"---------------------"<<endl;
ed=(isleap(yy)?lmon[mm]:pmon[mm]);
for(int i=0;i<6;i++)//将每个月份赋值到数组里
for(int j=(i==0?nweek(yy,mm,1)%7:0);j<7;j++)
if(k<=ed)
day[i][j]=k++;
for(int i=0;i<6;i++)
{
if(i==5&&!day[i][0])
break;
for(int j=0;j<7;j++)
{
if(!day[i][j])
cout<<" ";
else if(day[i][j]<10)//小于10右对齐
printf("%2d ",day[i][j]);
else//大于等于10
printf("%-3d",day[i][j]);
}
cout<<endl;
}
cout<<"---------------------"<<endl;
return 0;
}