1

我正在做 Project Euler #19。这里是状态:

您将获得以下信息,但您可能更愿意自己做一些研究。

1900 年 1 月 1 日是星期一。三十天有九月、四月、六月和十一月。其余的都有三十一个,仅保存二月,它有二十八,风雨无阻。在闰年,二十九。闰年出现在任何能被 4 整除的年份,但不会出现在一个世纪,除非它能被 400 整除。在 20 世纪(1901 年 1 月 1 日至 2000 年 12 月 31 日)有多少个星期日是一个月的第一天?

我在互联网上搜索了一些公式来计算星期几。我发现Zeller 公式非常出色。W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1.(C 是世纪 + 1,y 是年份的最后两个数字) 但是,当我检查 1900.01.01 时,结果是错误的,它应该是星期一,但根据公式,它是 6(即星期六)

我检查了很多日期,几乎所有日期都适合这个公式。但是还有更少的天数不匹配。对于这种情况,我的 Java 代码如下:

package number;

public class CountingSundays {
    public static int calculateWeek(int year, int month, int date){
        int c = year/100;
        int y = year%100;
        int w = c/4-2*c+y+y/4+13*(month+1)/5+date-1;
        w = (w%7 + 7)%7;
        return w;
    }
    public static void main(String[] args) {
//      int w = calculateWeek(1900, 01, 01);
//      System.out.println(w);
        int count = 0;
        for(int i = 1901; i <= 2000; i++)
            for(int j = 1; j <= 12; j++)
                if(calculateWeek(i, j, 01) == 0)
                    count++;
        System.out.println(count);
    }
}

对于不匹配,我的输出是 173,这不是所需的结果 171。任何人都可以给我一些提示吗?还是我的代码有问题?

4

3 回答 3

2

你引用的维基百科文章

m is the month (3 = March, 4 = April, 5 = May, ..., 14 = February)

For January 1, 2000, the date would be treated as the 13th month of 1999,
so the values would be:
    q = 1
    m = 13
    K = 99
    J = 19

所以你可能应该相应地调整你的输入值,如果你想使用这个公式,即添加这样的东西

if (month <= 2) {
    month += 12;
    year--;
}
于 2013-05-04T17:11:14.343 回答
2

如果您的意思是公历和英语,那么

GregorianCalendar gc = new GregorianCalendar(1, Calendar.JANUARY, 1900);
System.out.println(gc.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH));

输出

Monday

ETC

于 2013-05-04T17:01:55.243 回答
1

您可以遍历指定年份范围内的每个月并在 Calendar 对象上设置日期,然后读取每个月的第一天的星期几。

import java.util.Calendar;
import java.util.GregorianCalendar;

public class CountingSundays {

    public static void main(String[] args) {
        GregorianCalendar gc = new GregorianCalendar(1, Calendar.JANUARY, 1900);

        int count = 0;
        for (int i = 1901; i < 2001; i++) {
            gc.set(GregorianCalendar.YEAR, i);
            for (int j = 0; j < 12; j++) {
                gc.set(GregorianCalendar.MONTH, j);
                if (gc.get(GregorianCalendar.DAY_OF_WEEK) == GregorianCalendar.SUNDAY) {
                    count++;
                }
            }
        }
        System.out.println(count);
    }
}

请注意,循环中的年份和月份正在发生变化,但日期(月份中的某天)仍设置为第 1 天。

于 2013-05-04T17:38:31.217 回答