【问题标题】:Finding the day of the thirteenth of every month over a period of years查找多年来每个月的第十三天
【发布时间】:2010-11-08 11:02:25
【问题描述】:

我目前正在尝试解决 USACO 培训网站上的一些问题,为一场无关的 C++ 编程比赛做准备。

但是,我被这个问题困住了:

每个月 13 日在星期五的频率是否低于一周中的任何其他日子?要回答这个问题,请编写一个程序,计算在给定的 N 年期间每个月的 13 日在星期日、星期一、星期二、星期三、星期四、星期五和星期六出现的频率。测试的时间段是从 1900 年 1 月 1 日到 1900 年 12 月 31 日+N-1 个给定的年数,N 是非负数且不会超过 400。

数字 N 在输入文件中提供,输出将是一个包含七个数字的文件,每个数字代表一周中特定日期的 13 日的数字。

我想知道你们将如何解决这个问题。我不是在寻找代码或任何东西,因为那只会违背我这样做的目的,而只是一个起点或算法会有所帮助。

到目前为止,我唯一能想到的就是使用世界末日算法,但是我不确定如何在代码中实现它。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ calendar


    【解决方案1】:

    正如 Denny 所说,N 是如此之小,以至于您可以使用一个月中的天数表和一个简单的闰年谓词来处理二月,从而轻松地遍历月份。只需找出 1900 年 1 月 13 日是哪一天,然后将经过的天数相加,直到 2 月 13 日,然后是 3 月 13 日等等。使用% 运算符将经过的天数 # 包装回一周中的某一天价值。

    【讨论】:

    • 与我想到的所有崇高方法相比,这似乎是一种解决这个问题的简单方法。非常感谢您的启发!
    【解决方案2】:

    N 小于 400?好吧,您最多只需要超过 365.25*400=146100 天。听起来很容易枚举所有这些,将日期转换为年/月/日(使用您最喜欢的日期转换例程),测试星期几是微不足道的。

    不过我会预先计算表格。

    【讨论】:

      【解决方案3】:

      只需使用蛮力。比如这个pseudocode例子:

      from datetime import date
      
      day_names = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
                   'Saturday', 'Sunday']
      counts = [0] * 7
      for year in range(1900, 2300):
          for month in range(1, 13):
              counts[date(year, month, 13).weekday()] += 1
      for day, count in zip(day_names, counts):
          print('%s: %d' % (day, count))
      

      “硬”部分是calculating the day of the week a date falls on。在 C(++) 中,您可以使用 mktimelocaltime 库函数如果您知道您的平台可以处理足够大的日期范围。

      【讨论】:

      • “不会超过”表示范围(1900, 2301)
      • 假设您已获得“date(y,m,d).weekday()”功能是一件大事,尤其是因为 C++ 标准不包含它(大多数平台仅 time_t回到 1970 年)。虽然性能/效率在这里不是问题,但值得知道的是,这种转换在实践中非常昂贵,而且你做了很多不必要的事情。
      • @Tony:不过,从 1970 年倒退到 1900 年并不是真的非常困难。如果您不愿意从预先知道哪些年份是闰年开始,您可以从 1970 年开始工作,直到找到 2 月 29 日有效的年份(显然不超过 4 年)。从那里你可以向后工作,知道每四年将是一个闰年,除了 1900 年(世纪年不是闰年,除非它也是 400 的倍数)。完成此操作后,继续前进也很简单。
      • @Jerry:同意——这就是我提倡的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多