ZOJ-3939 The Lucky Week

Step1 Problem:

Lucky day means Monday is 1 or 11 or 21. Give the time of the first lucky day and ask the time of the nth lucky day.
For example:
2016 4 11 2
Output:
2016 7 11
Data range:
Time in normal range, 1<=n<=1e9

Step2 Involving algorithms:

Violence Watch

Step3 Ideas:

n It's very big. Violence must be out of time, so I think there's a cycle festival.
Assuming that our definition begins at 2016, 2014, we need to find out which years will appear on April 11.
For each difference that occurs during April 11, save it and then forcibly find the cycle section.
58 April 11 cycle
Get a 400-year cycle
2058 Lucky Days Cycle
Then the violent solution is enough.

Step4 Code:

//Dial up code
#include<bits/stdc++.h>
using namespace std;
int f(int m)
{
    if(m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
        return 31;
    else if(m == 4 || m == 6 || m == 9 || m == 11)
        return 30;
    else return 28;
}
int pdrn(int x)
{
    if(x%400==0 || (x%100!=0 && x%4==0))
        return 1;
    else return 0;
}
int a[100000];
int main()
{
    int T, y, m, d, n;
    cin >> T;
    while(T--)
    {
        int top = 0;
        scanf("%d %d %d %d", &y, &m, &d, &n);
        int cnt = 0;
        int num = 0, last = 0, flag = 0;
        for(int i = d; cnt <= 1000; i += 7)
        {
            int t = f(m);
            if(pdrn(y) && m == 2) t++;
            if(i > t) {
                m++;
                if(m > 12)
                {
                    y++;
                    m %= 12;
                }
                i %= t;
            }
           // printf("%d\n", t);
            if(i == 11 || i == 21 || i == 1)
            {
                //printf("~~%d %d %d\n", y, m, i);
                num++;
            }
            if(m == 4 && i == 11)
            {
                if(cnt % 58 == 0) printf("%d %d %d %d %d\n", y, m, d, num, num-last);
                a[top++] = num-last;
                last = num;
                cnt++;
            }
        }
        printf("~~\n");
        for(int len = 1; len <= 405; len++)
        {
            int i;
            for(i = 1; i+len < top; i++)
            {
                if(a[i] != a[i+len]) break;
            }
            if(i + len >= top) printf("%d\n", len);
        }
    }
    return 0;
}
//AC code
#include<bits/stdc++.h>
using namespace std;
int f(int m)
{
    if(m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
        return 31;
    else if(m == 4 || m == 6 || m == 9 || m == 11)
        return 30;
    else return 28;
}
int pdrn(int x)
{
    if(x%400==0 || (x%100!=0 && x%4==0))
        return 1;
    else return 0;
}
int a[100000];
int main()
{
    int T, y, m, d, n;
    cin >> T;
    while(T--)
    {
        scanf("%d %d %d %d", &y, &m, &d, &n);
        int n1 = n % 2058;
        int y1 = y + 400*(n/2058), i, cnt = 0;
        for(i = d; ; i += 7)
        {
            int t = f(m);
            if(pdrn(y1) && m == 2) t++;
            if(i > t)
            {
                m++;
                if(m > 12)
                {
                    y1++;
                    m %= 12;
                }
                i %= t;
            }
            if(i == 11 || i == 21 || i == 1)
                cnt++;
            if(cnt == n1) break;
        }
        printf("%d %d %d\n", y1, m, i);
    }
    return 0;
}

Posted by gabrielp on Wed, 06 Feb 2019 10:27:17 -0800