——题目来源于问答频道的网友提问
C++版本
#include <iostream> using namespace std; int daysinyear(int year) { return 365 + ((year%4==0 && year%100!=0) || year%400==0); } int count(int year1,int year2) { int t, total = 0; int weekday[3000-1900+1]; weekday[0] = 7; for (int i=1901;i<=3000;i++){ t = daysinyear(i) + weekday[i-1900 - 1] - 1; weekday[i-1900] = t % 7 + 1; } for (int i=year1;i<=year2;i++){ if (weekday[i-1900]==6 || weekday[i-1900]==7){ total++; } } return total; } int main () { int y1,y2; cin >> y1 >> y2; cout << count(y1,y2) << endl; return 0; }
稍作修改,可以输出所有满足条件的年份:
#include <iostream> using namespace std; int daysinyear(int year) { return 365 + ((year%4==0 && year%100!=0) || year%400==0); } void count(int year1,int year2) { int t, total=0; int weekday[3000-1900+1]; int years[3000-1900+1]; weekday[0] = 7; for (int i=1901;i<=3000;i++){ t = daysinyear(i) + weekday[i-1900 - 1] - 1; weekday[i-1900] = t % 7 + 1; } t = 0; for (int i=year1;i<=year2;i++){ if (weekday[i-1900]==6 || weekday[i-1900]==7){ total++; years[t++] = i; } } cout << year1 << "年到" << year2 << "年间符合要求的年份共有" ; cout << total << "个:" << endl; for (int i=0;i<total;i++){ cout << years[i] << " "; if (i%10==9) cout << endl; } cout << endl; } int main () { count(1900,3000); count(2018,2100); return 0; }
输出内容:
1900年到3000年间符合要求的年份共有314个:
1900 1905 1906 1911 1916 1917 1922 1923 1928 1933
1934 1939 1944 1945 1950 1951 1956 1961 1962 1967
1972 1973 1978 1979 1984 1989 1990 1995 2000 2001
2006 2007 2012 2017 2018 2023 2028 2029 2034 2035
2040 2045 2046 2051 2056 2057 2062 2063 2068 2073
2074 2079 2084 2085 2090 2091 2096 2102 2103 2108
2113 2114 2119 2124 2125 2130 2131 2136 2141 2142
2147 2152 2153 2158 2159 2164 2169 2170 2175 2180
2181 2186 2187 2192 2197 2198 2204 2209 2210 2215
2220 2221 2226 2227 2232 2237 2238 2243 2248 2249
2254 2255 2260 2265 2266 2271 2276 2277 2282 2283
2288 2293 2294 2299 2300 2305 2306 2311 2316 2317
2322 2323 2328 2333 2334 2339 2344 2345 2350 2351
2356 2361 2362 2367 2372 2373 2378 2379 2384 2389
2390 2395 2400 2401 2406 2407 2412 2417 2418 2423
2428 2429 2434 2435 2440 2445 2446 2451 2456 2457
2462 2463 2468 2473 2474 2479 2484 2485 2490 2491
2496 2502 2503 2508 2513 2514 2519 2524 2525 2530
2531 2536 2541 2542 2547 2552 2553 2558 2559 2564
2569 2570 2575 2580 2581 2586 2587 2592 2597 2598
2604 2609 2610 2615 2620 2621 2626 2627 2632 2637
2638 2643 2648 2649 2654 2655 2660 2665 2666 2671
2676 2677 2682 2683 2688 2693 2694 2699 2700 2705
2706 2711 2716 2717 2722 2723 2728 2733 2734 2739
2744 2745 2750 2751 2756 2761 2762 2767 2772 2773
2778 2779 2784 2789 2790 2795 2800 2801 2806 2807
2812 2817 2818 2823 2828 2829 2834 2835 2840 2845
2846 2851 2856 2857 2862 2863 2868 2873 2874 2879
2884 2885 2890 2891 2896 2902 2903 2908 2913 2914
2919 2924 2925 2930 2931 2936 2941 2942 2947 2952
2953 2958 2959 2964 2969 2970 2975 2980 2981 2986
2987 2992 2997 2998
2018年到2100年间符合要求的年份共有23个:
2018 2023 2028 2029 2034 2035 2040 2045 2046 2051
2056 2057 2062 2063 2068 2073 2074 2079 2084 2085
2090 2091 2096
--------------------------------
Process exited after 1.623 seconds with return value 0
请按任意键继续. . .
原本想用<ctime>库来验证:
#include <iostream> #include <ctime> using namespace std; int main () { time_t ltm; struct tm *info; time(<m); info = localtime(<m); for (int year = 1970; year<2038; year++){ info->tm_year = year - 1900; info->tm_mon = 11 - 1; info->tm_mday = 11; mktime(info); if ((info->tm_wday)==0 || (info->tm_wday)==6) cout << year <<endl; } return 0; } /* 1972 1973 1978 1979 1984 1989 1990 1995 2000 2001 2006 2007 2012 2017 2018 2023 2028 2029 2034 2035 */
后来发现只能正确输出这一段年份,百度了一下,原来它的CTime对象是有指定范围的:
static CTime WINAPI GetCurrentTime( );
获取系统当前日期和时间。返回表示当前日期和时间的CTime对象。
int GetYear( ) const;
获取CTime对象表示时间的年份。范围从1970年1月1日到2038年(包括2038年)1月18日。
python版本
python的日期时间库没有限制:
import datetime as dt years = [] for i in range(1900,3001): if dt.date(i,11,11).weekday() in [5,6]: years.append(i) m,n = map(int,input('请输入两个年份(1900~3000)').split()) total = list(filter(lambda x:m<=x<=n, years)) print(len(total),'\n满足条件的所有年份:\n',years)
还是python简洁,几行代码就能解决问题。