試題編號: 201503-3
試題名稱: 節日
時間限制: 1.0s
內存限制: 256.0MB
問題描述
有一類節日的日期並不是固定的,而是以“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.0s
內存限制: 256.0MB
問題描述
有一類節日的日期並不是固定的,而是以“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
分析:擦啊,真的是夠了,這道題讓我糾結了一個整整上午的時間。我一直認為自己的答案是正確的,找到樣例都是可以通過的。可是一直是40%的通過率,頭都快炸了。最后,我感覺是這道題有問題。而問題就是題目中給的描述:
如果該年的a月第b個星期c並不存在,則輸出"none"(不包含雙引號)。
我擦啊,正常人該怎么去理解這句話(紅色部分的)?好,下面舉個例子來說明這句話:

好了,我就將紅色的那句話作為一個不存在的判斷條件,對不,這可是題目給出的!
好下面是我第一次寫的代碼,並提交了,結果判定為40分。真是想不通了,我擦啊,對照着日歷一遍一遍輸入數據,結果都是正確的啊!想不通,真是想不通。
#include "stdafx.h" #include <iostream> #include <stdio.h> using namespace std; const int YEAR = 1850; int flag = 0; //平年和閏年的月份所含的天數 //daysOfMonth[0][]表示平年月份的天數 //daysOfMonth[1][]表示閏年月份的天數 int daysOfMonth[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; //判斷是否為閏年 void judgeIsLeapYear(int year) { if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) flag = 1; else flag = 0; } int cmpDays(int y, int m) { int days = 0; for (int i = YEAR; i < y; i++) { judgeIsLeapYear(i); if (flag == 1) days += 366; else days += 365; } judgeIsLeapYear(y); for (int i = 1; i <= m; i++) days += daysOfMonth[flag][i-1]; return days; } int main() { int a, b, c, y1, y2; int d1, d2; int dth;//每月一號是星期幾 while (scanf("%d%d%d%d%d", &a, &b, &c, &y1, &y2) != EOF) { for (int i = y1; i <= y2; i++) { d1 = cmpDays(i, a);//與1850年1月1日相差的天數 dth = d1 % 7 + 2;//當前a月1號是星期幾 if (dth == 0) dth = 7; //計算a月第b個星期星期c的具體日期 d2 = (b - 1) * 7 - dth + c + 1; if (b == 1 && c<dth || d2 > daysOfMonth[flag][b]) { printf("none\n"); continue; } if (d2 <= daysOfMonth[flag][a]) printf("%d/%02d/%02d\n", i, a, d2); } } return 0; }
絞盡腦汁了,我擦,修改一下,這個還是看的網上的一篇文章進行修改的,原來第一個星期是存在歧義的。例如上面給的例子,2016年1月1號是周五,那么第一個星期的周四、周三、周二、周日要從下周開始算起,才是第一周。
卧槽,真是一道廢題啊,拜拜花費了那么多時間。在此更正本篇文章,以免更多人誤解。
#include "stdafx.h" #include <iostream> #include <stdio.h> using namespace std; const int YEAR = 1850; int flag = 0; //平年和閏年的月份所含的天數 //daysOfMonth[0][]表示平年月份的天數 //daysOfMonth[1][]表示閏年月份的天數 int daysOfMonth[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; //判斷是否為閏年 void judgeIsLeapYear(int year) { if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) flag = 1; else flag = 0; } int cmpDays(int y, int m) { int days = 0; for (int i = YEAR; i < y; i++) { judgeIsLeapYear(i); if (flag == 1) days += 366; else days += 365; } judgeIsLeapYear(y); for (int i = 1; i <= m; i++) days += daysOfMonth[flag][i-1]; return days; } int main() { int a, b, c, y1, y2; int d1, d2; int count; int dth;//每月一號是星期幾 while (scanf("%d%d%d%d%d", &a, &b, &c, &y1, &y2)!= EOF) { for (int i = y1; i <= y2; i++) { d1 = cmpDays(i, a);//與1850年1月1日相差的天數 dth = d1 % 7 + 2;//當前a月1號是星期幾 //計算a月第b個星期星期c的具體日期
//如果當前輸入的星期c小於dth表示,第一周的星期c要從下一周算起。
if (c < dth) count = 1; else count = 2; d2 = 8 - dth + (b - count) * 7 + c; if (d2 <= daysOfMonth[flag][a]) printf("%d/%02d/%02d\n", i, a, d2); else printf("none\n"); } } return 0; }
給出本人的提交記錄:,尼瑪都是淚啊,希望以后考試不要出現這樣有歧義的題了,卡死人了!