我是编码的新手,我正在尝试为USACO中发布的“星期五第十三”问题编码,这要求我们计算每月13日在周日,周一,周二,周三登陆的频率,在给定的N年期间,周四,周五和周六。测试的时间段为1900年1月1日至1900年12月31日+ N-1,给定年数,N。N为正,不超过400。
1900年1月1日是星期一。我们不应该使用任何内置函数。
我尝试用不同的方法解决这个问题(我认为这不是最好的方法)。我的代码(在C中)如下:
#include<stdio.h>
int daysInMonth (int month, int year)
{
/*
30 should be returned if the months are Apr, June, Sept and Nov.
31 should be returned in all other cases.
29 should be returned if the month is Feb and the year is a leap year
*/
if (month == 1) //Feb
{
if (year % 4 == 0 || (year % 100 != 0 && year % 400 == 0)) //leap year
return 29;
else
return 28;
}
switch (month)
{
case 3:
case 5:
case 8:
case 10: return 30;
default: return 31;
}
}
void main ()
{
int month, year, n, i, noOfDays, start = 0, result[] = { 0, 0, 0, 0, 0, 0, 0 }, day = 0, daycheck = 1;
scanf ("%d", &n);
for (year = 1900; year <= 1900 + n - 1; ++year)
{
for (month = 0; month < 12; ++month)
{
if (month == 0 && year == 1900) // to identify the first 13th and the day it falls on
{
while (daycheck != 13)
{
++daycheck;
day = (day + 1) % 7;
}
++result[day];
}
else
{
if (month == 0) //If January, add the noOfDays of the prev. month i.e. December
noOfDays = 31;
else
noOfDays = daysInMonth (month - 1, year);
day += (noOfDays - 28); // Adding a multiple of 7 (here, 28) does not change the day
day %= 7;
++result[day];
}
}
}
for (i = 0; i < 7; ++i)
printf("%d ", result[(i + 5) % 7]); //Sat, Sun, Mon, Tue, Wed, Thu, Fri
}
输入为20时,预期输出为36 33 34 33 35 35 34。 但是,我的输出结果是35 35 33 35 32 35 35。
即使我的答案在预期输出的范围内,我的逻辑也出现了问题,导致错误。
如果有人可以指出错误,我将不胜感激。如果你能提出一个更好的方法来解决这个问题,我也会很高兴。我是计算机科学专业的学生,我还没有详细了解算法。
答案 0 :(得分:4)
您的闰年情况有误。
按如下方式更改闰年条件。
int daysInMonth (int month, int year)
{
if (month == 1) //Feb
{
if (( year%400 == 0)|| (( year%4 == 0 ) &&( year%100 != 0)))
return 29;
else
return 28;
}