UESTC 1299 Date 预处理、打表、找周期、前缀和

来源:互联网 发布:服务器php环境配置 编辑:程序博客网 时间:2024/05/29 02:47

Date

Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others)
 

A special day is the day that is xth day in that month, and happens to be xth day in that week.

In February 1st in 2016, this day in that month happens to be the first day in that week, so we call it a special day.

Now, given a time interval, how many special days in total?

Input

The first line is an integer T(T55), denoting the number of test cases.

Then T lines follows, each test case one line.

Each line contains two dates A and B, following such format: year month day.

year109  month and day will be legal.

A and B will all be later than 2016/1/31, and B will not be earlier than A.

Output

For each query, output the answer in one line.

Sample input and output

Sample InputSample Output
22016 2 1 2016 2 72016 2 1 2022 6 1
777

Hint

Note that the answer may be large, please using long long

Source

The 14th UESTC Programming Contest Preliminary

My Solution

too young too simple,当时初赛的时候,觉得必定会有一个周期,然后想不出该是怎样的周期,就不能猜几个试试看吗,先猜最特殊的呗
400 1200什么的,和闰年有关的数字
365 % 7 == 1
366 % 7 == 2
400年多出来的天数刚好可以被7整除,所以可得400年为一个周期
当时比赛的时候,笔者强行在万年历里面找规律,发现周期可能为28,确实28年多出了的也可以被7整除,但不够,不完整

赛后知道是400年为一个最小正周期,还是WA了3发,  主要是具体处理周期、周期总specialdays、输出时候的处理,


        if(cnt[y1][m1]){             
            if(d1 > 7) cout<<sum2-sum1<<endl;        //如果已经 d1 > 7了则可以直接减去
            else cout<<sum2-sum1+1<<endl;            //1 2 3 4 5 6 7  都是 + 1  因为当天是special day 但被减去了,要加上1
        }
        else cout<<sum2-sum1<<endl;                    //那个月没有special days ,直接减去即可

#include <iostream>#include <cstdio>#include <cstring>using namespace std;bool cnt[401][13];int date[13];bool runnian(int yr){    if(yr % 400 != 0) {if(yr % 100 == 0) return false;else if(yr % 4 != 0) return false; else return true;}    else return true;}int main(){    #ifdef LOCAL    freopen("a.txt", "r", stdin);    #endif // LOCAL    date[1]=31; date[2]=28; date[3]=31; date[4]=30; date[5]=31; date[6]=30; date[7]=31; date[8]=31; date[9]=30; date[10]=31; date[11]=30; date[12]=31;    int thedays;    long long specialday = 14;    memset(cnt, 0, sizeof cnt);    cnt[0][2]=1;    cnt[0][8]=1;    thedays = 335;    for(int i = 2017; i < 2016+400; i++){   //这个周期必须刚好,不然在算一个周期总共多少个 special days 的时候会出问题        for(int j = 1; j <= 12; j++){            thedays += date[j]; if(j == 2) thedays += runnian(i);  //if return true then add 1, else add 0    // only if  j == 2, we judge the runnian()            if(thedays % 7 == 0) {/*it is wrong cnt[i-2016][j+1 > 12 ? 1 : j+1] = true;*/                if(j != 12) cnt[i-2016][j + 1] = true;                else cnt[i-2016+1][1] = true;                specialday += 7;                if(i == 2415 && j == 12) specialday -= 7;            }        }    }    //从2016 1 1 到 2415 12 1/*  验证一下对不对    cout<<cnt[1][5]<<endl;    cout<<cnt[2][1]<<endl;    cout<<cnt[2][10]<<endl;    cout<<cnt[3][4]<<endl;    cout<<cnt[3][7]<<endl;    cout<<cnt[4][6]<<endl;    cout<<cnt[5][2]<<endl;    cout<<cnt[5][3]<<endl;    cout<<cnt[5][11]<<endl;*/    int T,y1,y2,m1,m2,d1,d2;    long long sum1,sum2;    scanf("%d", &T);    while(T--){        sum1 = 0;sum2 = 0;        scanf("%d%d%d%d%d%d", &y1, &m1, &d1, &y2, &m2, &d2);        long long t = (y1-2016)/400;sum1 += t*specialday;y1 = (y1-2016) % 400;        for(int i = 0; i < y1; i++){            for(int j = 1; j <= 12; j++)                if(cnt[i][j]) sum1 += 7;        }        for(int i = 1; i < m1; i++)            if(cnt[y1][i]) sum1 += 7;        if(cnt[y1][m1]){if(d1>7) sum1 += 7; else sum1 += d1;}//cout<<sum1<<endl;         //        t = (y2-2016)/400;sum2 += t*specialday;y2 = (y2-2016) % 400;        for(int i = 0; i < y2; i++){            for(int j = 1; j <= 12; j++)                if(cnt[i][j]) sum2 += 7;        }        for(int i = 1; i < m2; i++)            if(cnt[y2][i]) sum2 += 7;        if(cnt[y2][m2]){if(d2>7) sum2 += 7; else sum2 += d2;}//cout<<sum2<<endl;        if(cnt[y1][m1]){            if(d1 > 7)cout<<sum2-sum1<<endl;            else cout<<sum2-sum1+1<<endl;   //1 2 3 4 5 6 7        }        else cout<<sum2-sum1<<endl;    }    return 0;}


顺便贴上比赛时候的突发奇想查万年历,手动打表的,亏我想得出来,哈哈 ☺☺

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int cnt[10000][100];int main(){    memset(cnt, 0, sizeof cnt);    cnt[0][2]=1;    cnt[0][8]=1;    cnt[1][5]=1;    cnt[2][1]=1;    cnt[2][10]=1;    cnt[3][4]=1;    cnt[3][7]=1;    cnt[4][6]=1;    cnt[5][2]=1;    cnt[5][3]=1;    cnt[5][11]=1;    cnt[6][8]=1;    cnt[7][5]=1;    cnt[8][1]=1;    cnt[8][4]=1;    cnt[8][7]=1;    cnt[9][9]=1;    cnt[9][12]=1;    cnt[10][10]=1;    cnt[11][2]=1;    cnt[11][3]=1;    cnt[11][11]=1;    cnt[12][5]=1;    cnt[13][1]=1;    cnt[13][10]=1;    cnt[14][4]=1;    cnt[14][7]=1;    cnt[15][9]=1;    cnt[15][12]=1;    cnt[16][3]=1;    cnt[16][11]=1;    cnt[17][8]=1;    cnt[18][5]=1;    cnt[19][1]=1;    cnt[19][10]=1;    cnt[20][9]=1;    cnt[20][12]=1;    cnt[21][6]=1;    cnt[22][2]=1;    cnt[22][3]=1;    cnt[22][11]=1;    cnt[23][8]=1;    cnt[24][10]=1;    cnt[25][4]=1;    cnt[25][7]=1;    cnt[26][9]=1;    cnt[26][12]=1;    cnt[27][6]=1;    //freopen("a.txt", "r", stdin);    int T,y1,y2,m1,m2,d1,d2;    long long sum1,sum2;    scanf("%d", &T);    while(T--){        sum1 = 0;sum2 = 0;        scanf("%d%d%d%d%d%d", &y1, &m1, &d1, &y2, &m2, &d2);        long long t = (y1-2016)/28;sum1 += t*48;y1 = (y1-2016) % 28;        for(int i = 0; i < y1; i++){            for(int j = 1; j <= 12; j++)                if(cnt[i][j]) sum1++;        }        for(int i = 1; i < m1; i++)            if(cnt[y1][i]) sum1++;        if(cnt[y1][m1]){if(d1>7) sum1 += 7; else sum1 += d1;}//cout<<sum1<<endl;         //        t = (y2-2016)/28;sum2 += t*48;y2 = (y2-2016) % 28;        for(int i = 0; i < y2; i++){            for(int j = 1; j <= 12; j++)                if(cnt[i][j]) sum2 += 7;        }        for(int i = 1; i < m2; i++)            if(cnt[y2][i]) sum2 += 7;        if(cnt[y2][m2]){if(d2>7) sum2 += 7; else sum2 += d2;}//cout<<sum2<<endl;        cout<<sum2-sum1+1<<endl;    }    return 0;}

Thank you!


0 0
原创粉丝点击