zoukankan      html  css  js  c++  java
  • [Project Euler] 来做欧拉项目练习题吧: 题目019

                                [Project Euler] 来做欧拉项目练习题吧: 题目019

                                                  周银辉 

    题目描述:

    You are given the following information, but you may prefer to do some research for yourself.

    • 1 Jan 1900 was a Monday.
    • Thirty days has September,
      April, June and November.
      All the rest have thirty-one,
      Saving February alone,
      Which has twenty-eight, rain or shine.
      And on leap years, twenty-nine.
    • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

    How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)? 

    问题分析:

    计算从1901年到2000年间,有多少个星期天是在月初。

    题目说1900年1月1日是星期一,也就是说1900年1月7日是星期天,那么从这天开始每增加7天都是星期天。

    然后问题就转换成了这些星期天中哪些是在月初。

    高级语言都内置了日期函数,如果用类似于date.addDays(n)之类的函数,这个问题就变得非常简单了。

    不使用内置函数的话,就用下面的get_days和get_date方法吧:

    #include <stdio.h>
    long get_days(long y, long m, long d)
    {
    m = (m + 9)%12;                /* mar=0, feb=11 */
    y = y - m/10;                  /* if Jan/Feb, year-- */
    return y*365 + y/4 - y/100 + y/400 + (m*306 + 5)/10 + (d - 1);
    }
    void get_date(long days, long* y, long* m, long* d)
    {
    long yy, ddd, mm, dd, mi;
    yy = (10000*days + 14780)/3652425;
    ddd = days - (yy*365 + yy/4 - yy/100 + yy/400);
     
    if (ddd < 0) 
    {
    yy--;
    ddd = days - (yy*365 + yy/4 - yy/100 + yy/400);
    }
    mi = (52 + 100*ddd)/3060;
     
    *y = yy + (mi + 2)/12;
    *m = (mi + 2)%12 + 1;
    *d = ddd - (mi*306 + 5)/10 + 1;
    }
    int main()
    {
    long count = 0;
    long year  = 1900;
    long month;
    long day;
    long days = get_days(1900, 1, 7);
    while(1)
    {
    days += 7; //增加7天,肯定是星期天
    //取得该天的日期,判断其是否是1号
    get_date(days, &year, &month, &day);
    //printf("%ld-%ld-%ld\n", year, month, day);
    if (year>2000) 
    {
    break;
    }
    if(day==1 && year>=1901)
    {
    //今天是1号,那么至少要等28天以后才可能是1号了,下次循环是要加7天,所以这里加21天
    //避免无用的运算
    days  += 21; 
    count ++;
    }
    }
    printf("total count %ld\n", count);
    return 0;

    此题几乎不需要多少时间:

    real    0m0.005s
    user    0m0.001s
    sys     0m0.003s 

  • 相关阅读:
    二分LIS模板
    NYOJ16 矩形嵌套 【DAG上的DP/LIS】
    动态规划题库
    洛谷 P1616 疯狂的采药【裸完全背包】
    洛谷 P1049 装箱问题【正难则反/01背包】
    洛谷 P1048 采药【裸01背包】
    洛谷 P1064 金明的预算方案【有依赖的分组背包】
    洛谷 P1064 金明的预算方案【DP/01背包-方案数】
    洛谷 P1060 开心的金明【DP/01背包】
    51nod 1202 不同子序列个数 [计数DP]
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/2021468.html
Copyright © 2011-2022 走看看