【CCF】节日
问题描述
有一类节日的日期并不是固定的,而是以“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(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"(不包含双引号)。
如果该年的a月第b个星期c确实存在,则以"yyyy/mm/dd"的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠“/”分隔,位数不足时前补零。
如果该年的a月第b个星期c并不存在,则输出"none"(不包含双引号)。
样例输入
5 2 7 2014 2015
样例输出
2014/05/11
2015/05/10
2015/05/10
评测用例规模与约定
所有评测用例都满足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050。
分析
1. 函数firstday()用于计算每年的第一天是周几:如果前一年是闰年,今年是上一年的星期几+2;若不是闰年则是+1。
注意是判断上一年是否为闰年而不是本年,这个错误会导致日期计算错误。
2. 函数beforemonth()用于计算在某月之前一共有多少天,例如bm[5] = 120即5月1日前有120天。
3. 主函数中int fdom用于计算本月第一天是周几
4. 注意在主函数中判断是否是闰年之后,是2月之后的bm[]需要+1,不包括2月。
这个错误导致提交90分,找了好久没看出错误在哪。多了两个=号,谨记谨记!
5. 计算本月某一天是周几:(j-1)%7+fdom)%7 ,j是几号
总结
题目并不难,思路也不难,几次提交都错在了一些小点上,望改正。
1 #include <iostream> 2 #include <iomanip> 3 #include <cstdio> 4 #include <string.h> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 #include <string> 9 #include <queue> 10 #include <vector> 11 #include <set> 12 #include <list> 13 using namespace std; 14 typedef long long ll; 15 const int INF = 0x3f3f3f3f; 16 const int NINF = 0xc0c0c0c0; 17 const int maxn = 2005; 18 int MonthDay[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 19 string MonthName[] = {"Jan","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; 20 string DayName[] = {"Sun", "Mon","Tue","Wed","Thu","Fri","Sat"}; 21 bool isLeapYear(int year) 22 { 23 if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) return true; 24 else return false; 25 } 26 int fd[maxn]; 27 void firstday() 28 { 29 memset(fd, 0, sizeof(fd)); 30 fd[0] = 2; 31 for(int i = 1851; i <= 2050; i++) { 32 int t = i-1850; 33 int dd = 1; 34 if(isLeapYear(i-1)) dd++; 35 fd[t] = (fd[t-1]+dd)%7; 36 } 37 } 38 int bm[15]; 39 void beforemonth() 40 { 41 memset(bm, 0, sizeof(bm)); 42 bm[0] = 0; 43 for(int i = 1; i < 13; i++) { 44 bm[i] = bm[i-1] + MonthDay[i-1]; 45 // cout << i << "月,天数 = " << bm[i] << endl; 46 } 47 } 48 int main() {
50 firstday(); 51 beforemonth(); 52 int mon, day, dow, year1, year2; 53 cin >> mon >> day >> dow >> year1 >> year2; 54 if(dow == 7) dow = 0; 55 if(year1>year2) swap(year1,year2); 56 // cout << fd[2019-1850] << endl; 57 // for(int i = 1; i <= 12; i++) { 58 // cout << "first day of month "<< i << " = " << ((bm[i]%7+ fd[2018-1850])%7) << endl; 59 // } 60 for(int i = year1; i <= year2; i++) { 61 bool leap = false; 62 if(isLeapYear(i)) { 63 leap = true; 64 MonthDay[2]++; 65 if(mon>2) bm[mon]++; 66 } 67 int fdom = (bm[mon]%7+ fd[i-1850])%7; 68 // cout << bm[mon] << " " << bm[mon]%7 << " " << fd[i-1850] << " " << fdom << endl; 69 int cnt = 0; 70 for(int j = 1; j <= MonthDay[mon]; j++) { 71 if(((j-1)%7+fdom)%7 == dow) cnt++; 72 // if((j%7+fdom)%7-1 == dow) cnt++; 73 if(cnt == day) { 74 printf("%d/%02d/%02d\n", i, mon, j); 75 break; 76 } 77 } 78 if(cnt < day) cout << "none" << endl; 79 if(leap) { 80 MonthDay[2]--; 81 if(mon>2) bm[mon]--; 82 } 83 } 84 return 0; 85 }

浙公网安备 33010602011771号