道可道,非常道

无名者,圣人也
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[原创]USACO:Friday问题分析

Posted on 2008-03-21 16:35  一岩一道  阅读(249)  评论(0编辑  收藏  举报
问题简述:
    每个月的13号星期几?统计1900年到1900+N-1年内(如N=20,则统计到1919年12月31日)每个月13号的星期类型和出现次数。
    一些事实:
    1.在1900年1月1日这天为星期一。
    2.在9月,4月,6月和11月为30天,2月为28天,但在瑞年为29天。其他月份为31天。
    3.可以被4整除的年份为瑞年,但不包括世纪年份。世纪年份被400整除才为瑞年,如2000是瑞年,而1800,1900都不是。

分析:
这道题相对简单。只有计算出给定日期year年month月day日距1900年1月1日的天数就很好算出结果。
我们有一个函数GetDays(int year,int month,int day)来实现这个功能。
days=GetDays(1901,1,13);
weekday=days%7
依据weekday的值便可以确定相应的星期。
事实上,1900年1月1日这天为星期一,则weekday=0,为星期日,weekday=1为星期一。
然后使用两重循环,遍历每年的每月的13日,获得其对于天数,除7取余即可。
代码如下:
#include<iostream>
#include
<fstream>
#include
<string>

using namespace std;

int GetDays(int year, int month,int day);
bool IsLeapYear(int year);

int main()
{
    ofstream fout (
"friday.out");
    ifstream fin (
"friday.in");
    
int sb;
    fin
>>sb;
    
int year=1900+sb;
    
int friday=0;
    
int saturday=0;
    
int sunday=0;
    
int monday=0;
    
int tuesday=0;
    
int wednesday=0;
    
int thursday=0;
    
int days=0;
    
for(int i=1900;i<year;i++)
    
{
        
for(int m=1;m<13;m++)
        
{
            days
=GetDays(i,m,13);
            
int weekday=days%7;
            
if(weekday==0) sunday++;
            
if(weekday==1) monday++;
            
if(weekday==2) tuesday++;
            
if(weekday==3) wednesday++;
            
if(weekday==4) thursday++;
            
if(weekday==5) friday++;
            
if(weekday==6) saturday++;
        }

    }

    fout
<<saturday<<" "<<sunday<<" "<<monday<<" "<<tuesday<<" "<<wednesday<<" "<<thursday<<" "<<friday<<endl;
    
return 0;
}

int GetDays(int year, int month,int day)
{
    
int days=0;
    
int deltaDays=0;
    
for(int i=1900;i<year;i++)
    
{
        
if(IsLeapYear(i))
        
{
            deltaDays
=366;
        }

        
else
        
{
            deltaDays
=365;
        }

        days
=days+deltaDays;
    }

    
for(int i=1;i<month;i++)
    
{
        
if(i!=2){
            
if((i!=4)&&(i!=6)&&(i!=9)&&(i!=11))
                deltaDays
=31;
            
else
                deltaDays
=30;
        }

        
else
        
{
            
if(IsLeapYear(year))
                deltaDays
=29;
            
else
                deltaDays
=28;
        }

        days
=days+deltaDays;
    }

    days
=days+day;
    
return days;
}

bool IsLeapYear(int year)
{
    
if(year%400==0)
    
{
        
return true;
    }

    
else{
        
if(year%100==0return false;
        
if(year%4==0){
            
return true;
        }

        
else
        
{
            
return false;
        }

    }

}