在国外,每月的 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')
#include<stdio.h> int isLeapYear(int n){ int rtn=0; if(n%400==0 || (n%100!=0 && n%4==0))rtn=1; return rtn; } int main(){ char*L[7]={"1 4 7\n","9 12\n","6\n","3 11\n","2 8\n","5\n","10\n"}; char*C[7]={"1 10\n","4 7\n","9 12\n","6\n","2 3 11\n","8\n","5\n"}; int n; while(scanf("%d",&n)!=EOF){ int flag=isLeapYear(n); n=(6+(n-2000)+(n-1997)/4+(n-2001)/400-(n-2001)/100)%7; char*s; if(flag)s=L[n]; else s=C[n]; printf("%s",s); } return 0; }