【要求】
输入年、月、第几周、周几;如:2018 2 2 3(2018年2月第二周的周三)
输出对应的 年、月、日;2018-02-07(输出)
错误的输入输出0
【分析】
- 区分任意一年是否为闰年;闰年2月29天,否则是2月有28天;
- 一周的定义有2种:周一到周日为一周(1234567);周日到周六为一周(0123456)0为周日
- 第一周可能不全,即2018年2月第一周没有周二周三;
【思路】
- 判断是否为闰年
//判断是否是闰年
int IsLeapYear(int y)
{
if ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
return 1;
else return 0;
}
- 基姆拉尔森计算公式计算某年某月某日对应的星期
int CaculateWeekDay(int yy, int mm, int d)
{
if (mm == 1 || mm == 2) {
mm += 12;
yy--;
}
int iWeek = (d + 2 * mm + 3 * (mm + 1) / 5 + yy + yy / 4 - yy / 100 + yy / 400) % 7;
return iWeek + 1;
}
note:CaculateWeekDay函数返回值即星期几(返回7,星期日;返回2,星期二)
此计算公式可以输入任意日期,求得这个一天的星期
【Code】
#include<iostream>
#include<iomanip>
using namespace std;
//基姆拉尔森计算公式计算某年某月某日对应的星期
int CaculateWeekDay(int yy, int mm, int d)
{
if (mm == 1 || mm == 2) {
mm += 12;
yy--;
}
int iWeek = (d + 2 * mm + 3 * (mm + 1) / 5 + yy + yy / 4 - yy / 100 + yy / 400) % 7;
return iWeek + 1;
}
//注意这里的星期:周日-周六(一周的开始是周日)
int a[][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
int b[8] = { 0,1,2,3,4,5,6,0 };
//判断是否是闰年
int IsLeapYear(int y)
{
if ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
return 1;
else return 0;
}
int CaculateDay(int yy, int mm, int w, int n)
{
//输入判断是否符合条件
if (mm < 1 || mm > 12)return 0;
if (w < 1 || w > 6)return 0;
if (n < 1 || n > 7)return 0;
//计算每月1号星期几------》为下面判断周几是否有:
//如2019年7月1号是星期一,那么按照周日为一周的开始,则n=7,return 0;CaculateDay函数 按照此逻辑
//如果周一为一周开始,参考CaculateDay2函数
int days;
int week_day = CaculateWeekDay(yy, mm, 1);//计算每月1号星期
if (w == 1) {
//第一周需要检查n是否超过
if (b[n] < b[week_day])
return 0;
else
days = b[n] - b[week_day] + 1;
}
else {
days = b[6] - b[week_day] + 1;
days += (w - 2) * 7;
days += (b[n] + 1);
if (days <= 0 || days > a[IsLeapYear(yy)][mm - 1])
return 0;
}
return days;
}
int CaculateDay2(int yy, int mm, int w, int n)
{
//输入判断是否符合条件
if (mm < 1 || mm > 12)return 0;
if (w < 1 || w > 6)return 0;
if (n < 1 || n > 7)return 0;
int days;
int week_day = CaculateWeekDay(yy, mm, 1);//计算每月1号星期
if (w == 1) {
//第一周需要检查n是否超过
if (n < week_day)
return 0;
else
days = n - week_day + 1;
}
else {
days = 7 - week_day + 1;
days += (w - 2) * 7;
days += n;
if (days <= 0 || days > a[IsLeapYear(yy)][mm - 1])
return 0;
}
return days;
}
int main()
{
int yy, mm, w, n;
while (cin >> yy >> mm >> w >> n)
{
//int day = CaculateDay(yy, mm, w, n);
int day = CaculateDay2(yy, mm, w, n);
if (day == 0)
cout << day << endl;
else
{
cout << yy << "-" << setw(2) << setfill('0') << mm << "-" << setw(2) << setfill('0') << day << endl;
}
}
return 0;
}