USACO Friday the Thirteenth (Ad Hoc Problems)

题目大意:统计从1900年1月1号开始的n年时间内,每个月的13号落在星期一、星期二、星期三……星期日的次数。

分析:从今年某个月的13号到明年那个月的13号经过的时间恰好是一年,经过的天数可能是365或366,从今年的1月13到明年的1月13经过的天数是由今年的二月份的天数决定的,也就是由今年是否是闰年决定的,2月也是一样,但从今年的3月13到明年的3月13经过的天数是由明年的二月份的天数决定的,也即由明年是否是闰年决定,4、5、6、……12月也一样。

365%7=1

366%7=2

知道了以上2个算式,便可以从今年每月13的星期数推得明年的每月13的星期数,以后n年的都可以推出。递推的初始边界为1900年每月13的星期数,可由题中信息得出,也可查阅日历……

View Code
/*
ID: lijian42
LANG: C++
TASK: friday
*/
#include <stdio.h>
#include <string.h>
int d[12];
int cnt[7];
void init()
{
    d[0]=6;  d[1]=2;  d[2]=2;  d[3]=5;
    d[4]=0;  d[5]=3;  d[6]=5;  d[7]=1;
    d[8]=4;  d[9]=6;  d[10]=2;  d[11]=4;
}
bool IsLeap(int k)
{
    if(k%400==0 || k%4==0 && k%100!=0)   return true;
    return false;
}
void tran(int k)
{
    if(IsLeap(k))   for(int i=0;i<2;i++)   d[i]=(d[i]+1)%7;
    if(IsLeap(k+1)) for(int i=2;i<12;i++)   d[i]=(d[i]+1)%7;
    for(int i=0;i<12;i++)   d[i]=(d[i]+1)%7;
}
int main()
{
    freopen("friday.in","r",stdin);
    freopen("friday.out","w",stdout);
    int n,i,j;
    int test=0;
    while(~scanf("%d",&n))
    {
        memset(cnt,0,sizeof(cnt));
        init();
        for(i=0;i<n;i++)
        {
            for(j=0;j<12;j++)   cnt[d[j]]++;
            tran(1900+i);
        }
        printf("%d",cnt[6],cnt[0]);
        for(i=0;i<6;i++)    printf(" %d",cnt[i]);puts("");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/algorithms/archive/2012/07/20/2601786.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值