题目描述
有一类节日的日期并不是固定的,而是以“a 月的第 b 个星期 c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。
现在,给你 a,b,c 和 y1,y2,希望你输出从公元 y1 年到公元 y2 年间的每年的 a 月的第 b 个星期 c 的日期。
提示:关于闰年的规则:年份是 400 的整数倍时是闰年,否则年份是 4 的倍数并且不是 100 的倍数时是闰年,其他年份都不是闰年。
例如 1900 年就不是闰年,而 2000 年是闰年。
为了方便你推算,已知 1850 年 1 月 1 日是星期二。
输入格式
输入包含恰好一行,有五个整数 a,b,c,y1,y2。
其中 c=1,2,……,6,7 分别表示星期一、二、……、六、日。
输出格式
对于 y1 和 y2 之间的每一个年份,包括 y1 和 y2,按照年份从小到大的顺序输出一行。
如果该年的 a 月第 b 个星期 c 确实存在,则以 yyyy/mm/dd 的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠 / 分隔,位数不足时前补零。
如果该年的 a 月第 b 个星期 c 并不存在,则输出 none。
数据范围
1≤a≤12,
1≤b≤5,
1≤c≤7,
1850≤y1,y2≤2050
输入样例:
5 2 7 2014 2015
输出样例:
2014/05/11
2015/05/10
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
/*
本题模拟步骤:
1.从1850年1月1日开始枚举,枚举到y2
2.每一年内枚举月份1~12,算一下每年每月的1号距离1850年1月1日过了多少天(因为要求星期几),过了的天数%7加上1850年1月1日星期二(题目已知条件)的下标(这里下标用0~6表示星期一到星期七)就可以得到某年某月的1日是星期几
3.判断a月份时,求一下a月份的第b个星期c,看下是否存在
*/
int months[13]={ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int is_leap(int year)
{
if((year%4==0 && year%100) || year%400==0)
return 1;
return 0;
}
int get_days(int year,int month)//求某月多少天
{
if(month==2) return months[month]+is_leap(year);//闰年2月29天
return months[month];
}
//星期一到星期日用0~6表示
int main()
{
int a,b,c,y1,y2;
cin>>a>>b>>c>>y1>>y2;
int days = 0;//表示过了多少天
for(int year = 1850; year<=y2; year++)
for(int month = 1; month<=12; month++)
{
if(year >=y1 && month == a)
{
int w = (1+days) % 7;//先算一下这个月的1月1号是星期几
int cnt = 0;//统计一下当前是枚举到第几个星期c
for(int d = 1; d<=get_days(year,month); d++)//枚举一下这个月的所有天
{
if(w == c-1)//星期的下标从0开始,所以c-1
cnt++;//星期c的个数++
if(cnt == b)//如果星期c的个数等于b的话,满足条件,输出
{
printf("%04d/%02d/%02d\n",year,month,d);
break;
}
w = (w+1)%7;//每过完一天,星期++(在0到6内)
}
//枚举完这个月的所有天后,星期c出现的次数小于b,说明没有第b个星期c,输出none
if(cnt<b) puts("none");
}
days += get_days(year,month);//枚举完当前月份后,加上当前月份过的天数
}
return 0;
}