USACO习题:Friday the Thirteenth

这道题难度不大,就是比较麻烦。求解所有月份13号是星期几。

 

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

const int MONTHS[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
vector<int> ACC_MONTHS(13,0);
vector<int> ACC_LEAP_MONTHS(13,0);


bool is_leap_year(int year);

void accumulate_months(vector<int> &acc_months,bool is_leap){
int count=0;
for(int i=0;i<=12;i++){
int days = MONTHS[i];
if(i==2&&is_leap)
days+=1;
count+=days;
acc_months[i] = count;
}
}


int first_day_of_year(int year){
int d=0;
for(int i=1901;i<=year;++i){
int days = 365;
if(is_leap_year(i-1))
days=366;
d = (d+days)%7;
}
return d;
}

int weekday(int year,int month,int day,int first_day){
vector<int> *acc_months = &ACC_MONTHS;
if(is_leap_year(year))
acc_months = &ACC_LEAP_MONTHS;
return ((*acc_months)[month-1]+day-1+first_day)%7;
}


bool is_leap_year(int year){
if(year%400==0)
return true;
else if( (year%4==0) && (year%100!=0) )
return true;
else
return false;
}

void solve(int N, vector<int> &stat){
for(int i =1900;i<1900+N;++i){
int first_day = first_day_of_year(i);
//cout<<i<<":"<<first_day<<endl;
for(int month=1;month<=12;++month){
int name = weekday(i,month,13,first_day);
stat[name]+=1;
}
}

}

int main() {
ofstream fout("friday.out");
ifstream fin("friday.in");

accumulate_months(ACC_MONTHS,false);
accumulate_months(ACC_LEAP_MONTHS,true);


int N=0;
fin>>N;
//stat:start from monday(0) to Sunday(6)
vector<int> stat(7,0);
solve(N,stat);

for(int i=0;i<7;++i){
fout<<stat[(i+5)%7];
if(i<6)
fout<<" ";
}
fout<<endl;

fin.close();
fout.close();
return 0;
}



posted on 2012-03-18 21:38  lzyzizi  阅读(136)  评论(0编辑  收藏  举报

导航