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

ProLightsfx 2017-8-7 130 8/7

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

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 
#include 
#include 
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 
#include 
#include 
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;
}

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

https://www.prolightsfxjh.com/

Thank you!

                                                                                                                                             ------from ProLightsfx

 

- THE END -

ProLightsfx

11月15日11:15

最后修改:2024年11月15日
0

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

共有 0 条评论