CCF——節日
阿新 • • 發佈:2019-01-09
問題描述:
有一類節日的日期並不是固定的,而是以“a月的第b個星期c”的形式定下來的,比如說母親節就定為每年的五月的第二個星期日。
現在,給你a,b,c和y1, y2(1850 ≤ y1, y2 ≤ 2050),希望你輸出從公元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”(不包含雙引號)。
樣例輸入:
5 2 7 2014 2015
樣例輸出
2014/05/11
2015/05/10
約定
滿足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050。
思路:
此題主要還是求日期,看題目要求,覺得做個日曆表出來,直接查詢就了當完事,不過看到題目後面,假設1850年的1月1日為週二,就決定放棄這條選擇了,1850年到2015年,這中間的資料得記錄多少,而且某些還不用,所以太過浪費時間。再想想,採用每週的週期來求解,1850年的第一個週二是1月1日,那麼第二個週二不就是1月8日嗎,中間相乘一個週期——7,那麼明年的1月1日是周幾,直接用今年的所有天數對7進行求餘數即可,為0代表週日,其餘分別代表週一,週二,週三,週四,週五,週六。那麼基本解法就出來了。
Code:
#include <iostream>
using namespace std;
int a1[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //平年
int a2 = 29; //閏年,2月是29天
int main()
{
int m, n, day, y1, y2;
while (cin >> m >> n >> day >> y1 >> y2)
{
day %= 7 ;
int s = 0;
//統計天數
for (int i = 1850; i < y1; i++)
{
if ((i % 4 == 0 && i % 100 != 0) || (i% 400 == 0))
s += 366;
else
s += 365;
}
for (int i = y1; i <= y2; i++)
{
int t = 0;
int _day = 0;
bool flag = false;
int _current = 0;
int _m = 0; //儲存日期號數
if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0))
flag = true;
//計算當年的前幾個月的天數
for (int j = 0; j < m - 1; j++)
if (j == 1 && flag == true)
t += a2;
else
t += a1[j];
s += t;
s += 2;
int _tes = s % 7;
//進行判斷是該月的周幾,多少號
for (int k = 0; k < n; k++)
for (int p = 1; p <= 7; p++)
{
t++;
if (_tes % 7 == day&&k==n-1)
_m = _current;
_tes++;
_current++;
}
s -= t;
s -= 2;
//計算完當年
if (flag)
s += 366;
else
s += 365;
//按照格式輸出
if (n > 4)
{
cout << "none" << endl;
continue;
}
if (m < 10)
{
cout << i << "/" << "0" << m << "/";
}
else
cout << i << "/" << m << "/";
if (_m< 10)
{
if (_m==0)
{
cout << "0" << _m+1 << endl;
}
else
cout << "0" << _m << endl;
}
else
cout << _m << endl;
}
}
return 0;
}