题目链接:https://www.luogu.com.cn/problem/P1202
知识点:直接暴力(很简单,但因一处逻辑没完全理顺导致查了一个小时才查出来错误,于是十分爆炸地敲下这篇题解)
思路:
1.闰年特判
( 是 4 的倍数 && 不是 100 的倍数 ) || ( 是 400 的倍数 )
我当时错误的点,不在于怎么判断闰年,而是:
int year = 1900;
for ( int i = 0; i < n; ++ i )
{
year += i; // 这里增加年份极其错误!
if ( ) {} // 特判闰年
}
2.计算13号是周几:将累积到13号的总天数取余
完整代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int ans[ 8 ];
int month[ 13 ] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int check ( int x )
{
if ( ( x % 4 == 0 && x % 100 != 0 ) || ( x % 400 == 0 ) )
{
return 1;
}
else
return 0;
}
void solve ( )
{
int year = 1900;
int day = 0;
for ( int i = 0; i < n; ++ i )
{
if ( check ( year + i ) ) month[ 2 ]=29; // 闰年特判
for ( int j = 1; j <= 12; ++ j )
{
++ ans[ (day + 13) % 7 ]; // 13号周几
day += month[ j ]; // 月末
}
month[ 2 ] = 28;
}
// for ( int i = 0; i < 7; ++ i )
// {
// printf ( "%d ", ans[ i ] );
// }
printf ( "%d %d ", ans[ 6 ], ans[ 0 ] );
for ( int i = 1; i < 6; ++ i )
{
printf ( "%d ", ans[ i ] );
}
puts ( "" );
}
int main ( )
{
scanf( "%d", &n );
solve();
// system ( "pause" );
return 0;
}
另外,也可以采用数学公式:
基姆拉尔森计算公式:
𝑤𝑒𝑒𝑘 = ( 𝑑𝑎𝑦 + 2 × 𝑚𝑜𝑛𝑡ℎ + [ 3 × ( 𝑚𝑜𝑛𝑡ℎ + 1 ) / 5 ] + 𝑦𝑒𝑎𝑟 + [ 𝑦𝑒𝑎𝑟 / 4 ] − [ 𝑦𝑒𝑎𝑟 / 100 ] +[ 𝑦𝑒𝑎𝑟 / 400 ] + 1 ) mod 7
注意:该公式将每年的11月与22月份作为前一年的13与14月份进行计算,所以需要在代码中进行一个小小的特判。 即:
int weekDay ( int year, int month, int day )
{
if ( month == 1 || month == 2 )
{
month += 12;
-- year;
}
return ( day + 2 * month + 3 * ( month + 1 ) / 5 + year + year / 4 - year / 100 + year / 400 + 1 ) % 7;
}
see you next time.