【CCF】节日

问题描述
  有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。
  现在,给你abcy1y2(1850 ≤ y1y2 ≤ 2050),希望你输出从公元y1年到公元y2年间的每年的a月的第b个星期c的日期。
  提示:关于闰年的规则:年份是400的整数倍时是闰年,否则年份是4的倍数并且不是100的倍数时是闰年,其他年份都不是闰年。例如1900年就不是闰年,而2000年是闰年。
  为了方便你推算,已知1850年1月1日是星期二。
输入格式
  输入包含恰好一行,有五个整数abcy1y2。其中c=1, 2, ……, 6, 7分别表示星期一、二、……、六、日。
输出格式
  对于y1y2之间的每一个年份,包括y1y2,按照年份从小到大的顺序输出一行。
  如果该年的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 ≤ y1y2 ≤ 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 }

 

posted @ 2018-03-09 11:07  kikii233  阅读(201)  评论(0)    收藏  举报