USACO-Section1.2 Friday the Thirteenth (简单日期处理)

2017-5-24
2018-3-25 changed

题目描述

输入N表示年数,算出从190011日到1900+N-11231日每个月13号为星期几,
输出周6,7,1,2,3,4,5的天数

解答

我是求出每个月距离1900年1月1日的天数然后对7求余即可,注意处理平年和闰年

代码

/*
ID: 18795871
PROG: friday
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

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

int day[2][13] = {31,31,28,31,30,31,30,31,31,30,31,30,0,31,31,29,31,30,31,30,31,31,30,31,30,0};
int r[8];

int res(int n){
    if (n%4==0 && n%100!=0 || n%400==0) return 1;
    return 0;
}

int main(){
    int i,n;
    fin>>n;
    memset(r,0,sizeof(r));
    r[6]=1;
    int sum = 12,year = 1900,p;
    for (i=1 ;i<=12*n-1 ;i++){
        p = res(year);
        sum += day[p][i%12];
        r[sum%7+1] += 1;
        if (i%12 == 0) year += 1;
    }
    fout<<r[6]<<" "<<r[7]<<" ";
    for (i=1; i<=4; i++) fout<<r[i]<<" ";
    fout<<r[5]<<endl;
    return 0;
}

上面的代码应该是按照月份进行相加,相差的天数每次加一个月的天数那么多。
下面的代码是调用函数计算两个日期之间相差的天数。

/*
ID: 18795871
PROG: friday
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

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

int year[2][1]={365,366};
int day[2][12]={31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31};
int res[7];
int n;

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

int cal(int y,int m,int d){
    int i,j,s=0;
    for (i=1900;i<y;i++){
        s+=year[isLeap(i)][0];
    }
    j=isLeap(y);
    for (i=0;i<m-1;i++){
        s+=day[j][i];
    }
    s+=(d-1);
    return s;
}

int main(){
    while (fin>>n){
        memset(res,0,sizeof(res));
        int sum=0,i,j;
        for (i=1900;i<1900+n;i++){
            for (j=1;j<=12;j++){
                sum=cal(i,j,13);
                res[sum%7]++;
            }
        }
        for (i=5;i<7;i++){
            fout<<res[i]<<" "; 
        }
        for (i=0;i<4;i++){
            fout<<res[i]<<" ";
        }
        fout<<res[i]<<endl;
    }
    return 0;
}

又或者是这样。

/*
ID: 18795871
PROG: friday
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

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

int day[2][12]={31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31};
int res[7];
int n;

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

int main(){
    while (fin>>n){
        memset(res,0,sizeof(res));
        int sum=12,i,j,k;
        res[5]=1;
        for (i=1900;i<1900+n;i++){
            k=isLeap(i);
            for (j=0;j<12;j++){
                sum+=day[k][j];
                res[sum%7]++;
            } 
        }
        res[sum%7]--;
        for (i=5;i<7;i++){
            fout<<res[i]<<" "; 
        }
        for (i=0;i<4;i++){
            fout<<res[i]<<" ";
        }
        fout<<res[i]<<endl;
    }
    return 0;
}

需要注意的是,sum初始化应该为12,res[5]=1,因为我们第一次加的是31,也就是第一个月的天数,所以我们要把1900/1/13周几先计算出来,当然最后要再res[sum%7]–,因为我们十二月份多算了一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值