在国外,每月的 13 号和每周的星期 5 都是不吉利的。特别是当 13 号那天恰好是星期 5时,更不吉利。
现在给你一个年份,请你从小到大依次输出当年所有13 号是星期 5 的月份。
输入包含多组数据,每组数据包含一个正整数year(2000≤year≤9999)。
对应每一组数据,输出所有符合条件的月份,月份之间用空格隔开。
如果当年不存在13号是星期五的月份,就输出一行Luck。
2000<br/>2001<br/>2002
10<br/>4 7<br/>9 12
计算 周几 使用 吉姆拉尔森 算法 #include <iostream> #include <algorithm> using namespace std; int month31[] = { 1,3,5,7,8,10,12 }; int CalculateWeekDay(int y, int m, int d) { if (m == 1 || m == 2) m += 12, y--; int iWeek = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; return iWeek; } int main() { int year; while (cin >> year) { int cnt = 0; for (int i = 1; i < 13; i++) { if (CalculateWeekDay(year, i, 13) % 7 == 4) { cnt++; if(cnt == 1) cout << i; else { cout << " " << i; } } } if (!cnt) { cout << "Luck" << endl; } else { cout << endl; } } } 当然,使用C 的time.h 也是很好用的,不用计算,爽。 而且好记 #include <iostream> #include <time.h> #include <vector> #include <fstream> using namespace std; #ifndef debug ifstream ifile("case.txt"); #define cin ifile #endif int main() { struct tm timeInfo; int year; int month; int day; time_t rawtime; time(&rawtime); timeInfo = *localtime(&rawtime);// raw 应该是时间基线,不是特别清楚。 while (cin >> year){ timeInfo.tm_year = year - 1900; vector<int> count; for (int i = 0; i < 12; i++){ month = i; day = 13; timeInfo.tm_mon = i; timeInfo.tm_mday = 13; mktime(&timeInfo); if (timeInfo.tm_wday == 5) {// 如果日期等于5 count.push_back(i+1); } } if (count.size() == 0) { cout << "Luck" << endl; } else { cout << count[0]; for (int i = 1; i < count.size(); i++) { cout << " " << count[i]; } cout << endl; } } system("pause"); }
#include<bits/stdc++.h> using namespace std; //思路 以2000 年10 月13日(星期五)为起点。算 给定年份的每个月的13号与2000 10 13天数差值(最大10000*365不超过int范围) //如果差值是7的倍数 则输出当月月份即可 int daylab[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}; bool IsLeap(int n){ if((n%4==0&&n%100!=0)||(n%400==0)) return true; else return false; } int main(){ int n; while(cin>>n){ int sum=79;//2000年还剩79天 if(n==2000) cout<<"10"<<endl; else{ for(int i=2001;i<n;i++){//计算到前一年的天数差值 if(IsLeap(i)==true){ sum+=366; }else{ sum+=365; } } //加上给定年份当年的差值 for(int i=1;i<=12;i++){ sum+=13; if(sum%7==0) cout<<i<<' '; sum-=13; sum+=daylab[IsLeap(n)][i]; } cout<<endl; } } return 0; }
#include<stdio.h> char* s[][7]={{"1 10","4 7","9 12","6","2 3 11","8","5"},{"1 4 7","9 12","6","3 11","2 8","5","10"}}; int main(int y){//the shorter,the better. for(;~scanf("%d",&y);printf("%s\n",s[y%400==0||(y%100!=0&&y%4==0)][(6+(y-2000)+(y-1997)/4+(y-2001)/400-(y-2001)/100)%7])); }
#include <iostream> using namespace std; void get_num_unlucky(int year) { int day = (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400; //前一年一共有多少天 int type[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; int kind = 1; if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) kind = 0; day += 13; for (size_t i = 0; i < 12; i++) { if (day % 7 == 5) cout << i + 1 << " "; day += type[kind][i]; } cout << endl; } int main() { int year; while (cin >> year) { get_num_unlucky(year); } return 0; }
这道题并不复杂,但是在细节控制方面有点繁琐。
我们要解决的问题是计算当年每个月的13号是星期几,年份输入的范围是2000≤year≤9999
,直接求解可能比较难,我们一步一步逼近。
首先我们需要计算出输入年份的1月1日
是星期几week
,我们查找网络知2000年1月1日
是星期六
。
平年一年365天(52周+1天),闰年一年366天(52周+2天)。
也就是说平年一年过去后week = (week + 1) % 7
,闰年一年过去后week = (week + 2) % 7
,实际效果是闰年 = 平年 + 1
因此我们需要计算[2000, yea)
中有多少个闰年[2000, yea)
期间总共有year - 2000
年,闰年数量为(year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400
==注意:== 我们这里把2000年单独拿出来,因为当year == 2000
时,2000年的闰年并不会影响2000年1月1号的计算。
因此==year年1月1日星期几week求解计算==过程为
int week = 6;//2000年1月1日 星期六,注意星期日用0表示 //计算该年1月1日星期几,平年365天(52周+1天)闰年366(52周+2天),也就是平年增加一天,闰年增加两天 //期间year - 2000年,(year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400 个闰年 week = (week + (year - 2000) + (year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400) % 7; if (year > 2000) { //2000年也是l闰年,但是单独算,因为当year == 2000时,此时它虽是闰年,但是不影响2000年1月1日是星期几的计算 week += 1; }
知道了year年1月1日
是星期几,记为week0
,那么
year年1月12日 week1 = (week0 + 12) % 7 year年2月12日 week2 = (week0 + 31 + 12) % 7 注:1月31天 year年3月12日 week3 = (week0 + 31 + 28 or 29 + 12) % 7 注:平年 2月 28天,闰年 2月 29天 year年4月12日 week4 = (week0 + 31 + 28 or 29 + 31 + 12) % 7 注:3月 31天 ...
#include <iostream> using namespace std; int main() { int resTable[12] = {0}, year = 0; //resTable存放当年13号为星期5的月份,monthDays[month]记录month月的天数,其中2月根据year是否为闰年动态调整 int monthDays[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //scanf函数范围值为正确获取到数据的参数个数,当没有输入返回-1 while (scanf("%d", &year) != -1){ //2000年1月1日 星期六,注意星期日用0表示,count记录13 号是星期 5 的月份个数 int week = 6, count = 0; //计算该年1月1日星期几,平年365天(52周+1天)闰年366(52周+2天),也就是平年增加一天,闰年增加两天 //期间year - 2000年,(year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400 个闰年 week = (week + (year - 2000) + (year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400) % 7; if (year > 2000) { //2000年也是l闰年,但是单独算,因为当year == 2000时,此时它虽是闰年,但是不影响2000年1月1日是星期几的计算 week += 1; } //如果当年是闰年,则二月有29天 if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { monthDays[2] = 29; } else { monthDays[2] = 28; } //判断当年的每个月13号是不是星期5 for (int month = 1; month < 13; ++month) { if ((week + 12) % 7 == 5) { //如果是就记录掉resTable中,count记录13 号是星期 5 的月份个数 resTable[count++] = month; } //转到下个月的1号 week += monthDays[month]; } for (int i = 0; i < count - 1; ++i) { printf("%d ", resTable[i]); } printf("%d\n", resTable[count - 1]); } return 0; } ———————————————— 版权声明:本文为CSDN博主「hestyle」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://hestyle.blog.csdn.net/article/details/104717957
#include <stdio.h> #include <stdlib.h> int leap[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int comm[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int is_leap(int year) { if(year % 100 == 0) { if(year % 400 == 0) return 1; return 0; } if(year % 4 == 0) return 1; return 0; } int main() { int year; while(~scanf("%d", &year)) { int start = 2000; int total_day = 92; if(year == start) { printf("10\n"); continue; } while((start + 1) != year) { if(is_leap(start+1)) total_day += 366; else total_day += 365; start++; } start++; int temp = 0; for(int i = 1; i <= 12; i++) { if(is_leap(start)) { if(total_day % 7 == 0) { if(temp == 0) printf("%d", i); else printf(" %d", i); temp = 1; } total_day += leap[i]; } else { if(total_day % 7 == 0) { if(temp == 0) printf("%d", i); else printf(" %d", i); temp = 1; } total_day += comm[i]; } } if(temp == 0) printf("Luck"); printf("\n"); } return 0; }以2000.10.13为起始点就行了
#include <cstdio> int main(int argc, char const *argv[]){ int year; while(scanf("%d", &year) != EOF){ int cnt = 0; for (int month = 1; month <= 12; ++month) { int y = year; int d = 13; int m = month; if(m==1||m==2){ y = year - 1; m+=12; } int w =(d+1+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; if(w == 5){ if(cnt != 0) printf(" "); if(m > 12){ printf("%d", m -12); }else{ printf("%d", m); } cnt++; } } if(cnt == 0){ printf("Luck"); } printf("\n"); } return 0; }
import calendar while True: try: n=int(input()) a=[] for i in range(1,13): if calendar.monthrange(n,i)[0]==6: a.append(str(i)) if a: print(" ".join(a)) else: print("Luck") except: break
def day(a,b,nian,yue): con = (a+a//4+a//400-a//100-nian+yue+13)%7 if con==5: return True else: return False def ifrun(a): if a%400==0: return True elif a%100==0: return False elif a%4==0: return True else: return False pinlst = [0,3,3,6,1,4,6,2,5,0,3,5] runlst = [0,3,4,0,2,5,0,3,6,1,4,6] try: while True: n = input() n = int(n) zong = 0 out = [] if ifrun(n): for i in range(1,13): if day(n,i,2,runlst[i-1]): out.append(str(i)) else: for i in range(1,13): if day(n,i,1,pinlst[i-1]): out.append(str(i)) print(" ".join(out)) except: pass通过蔡勒公式进行计算
//大神们写得都过于牛逼,看不懂,还是自己动手
#include<stdio.h>
int isLeapYear(int n);
int main()
{
int i, y;
while(scanf("%d", &y)!=EOF)
{
int days = 4; //根据示例可以推算出2000年的1月13日是星期四
int count = 0;
for(i=2000; i<y; i++)
{
if(isLeapYear(i)==1)
{
days += 366;
}
else
{
days += 365;
}
days %= 7;
}
for(i=1; i<13; i++)
{
if(days==5)
{
if(count)
{
printf(" ");
}
printf("%d", i);
count++;
}
if(i==1||i==3||i==5||i==7||i==8||i==10)
{
days += 31;
}
else if(i==2)
{
if(isLeapYear(y)==1)
{
days += 29;
}
else
{
days += 28;
}
}
else
{
days += 30;
} days %= 7;
}
printf("\n");
}
return 0;
}
int isLeapYear(int n)
{
int rtn=0;
if(n%400==0 || (n%100!=0 && n%4==0))
{
rtn=1;
}
return rtn;
}
#include<stdio.h> int num[13]={0,31,-1,31,30,31,30,31,31,30,31,30,31}; int temp[13]={0,12,1,2,3,4,5,6,7,8,9,10,11}; int a[8000][12]; int RunYear(int n) { if((n%4==0&&n%100!=0) || n%400==0)//闰年2月29天 return 29; else return 28; } int main() { //2000≤year≤9999 int i,j,n,year,cnt=0,week=3;//week代表2000年12月13日是星期三 a[0][0]=2;//一个满足 a[0][1]=10;//10月份 for(i=1;i<=7999;i++) { year=i+2000; cnt=1; num[2]=RunYear(year); for(j=1;j<=12;j++)//i+1 年 { week=(week+num[temp[j]]%7)%7; //printf("%d年%d月13日:星期%d\n",i+2000,j,week); if(week%7==5) a[i][cnt++]=j; } a[i][0]=cnt; } while(~scanf("%d",&n)) { cnt=a[n-2000][0]; if(cnt==1)printf("Luck\n"); else { for(i=1;i<=cnt-2;i++) printf("%d ",a[n-2000][i]); printf("%d\n",a[n-2000][cnt-1]); } } return 0; }
bad_luck_day(List) -> ResultList = [bad_luck_day(Year, 1, []) || Year <- List], Fun = fun(MonthList) -> [io:format("~p ", [X]) || X <- MonthList], io:format("~n") end, lists:foreach(Fun, ResultList). bad_luck_day(_Year, Num, Result) when Num > 12 -> lists:reverse(Result); bad_luck_day(Year, Num, Result) -> Week = calendar:day_of_the_week({Year,Num,13}), if Week =:= 5 -> bad_luck_day(Year, Num+1, [Num|Result]); true -> bad_luck_day(Year, Num+1, Result) end.
def whichDay(year, month, day): rlt = 0 month -= 1 while month>0: if month in [1, 3, 5, 7, 8, 10, 12]: rlt += 31 else: if month!=2: rlt += 30 else: rlt += 28 if (year%4==0 and year%100!=0) or year%400==0: rlt += 1 month -= 1 return (365*(year-1)+((year-1)//4 - (year-1)//100 + (year-1)//400) + rlt + day) while True: try: year = input() year = int(year) except: break cnt = 0 rlt = '' for month in range(1, 13): if (whichDay(year, month, 13)%7) == 5: if cnt: rlt += ' ' rlt += str(month) cnt += 1 if cnt: print(rlt) else: print('Luck')