Skip to content

11509: 【原1509】节日计算器

题目

题目描述

author: 金耀楠 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1509

Description

有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。

现在,给你a,b,c和y1, y2(1850 ≤ y1, y2 ≤ 2050),希望你输出从公元y1年到公元y2年间的每年的a月的第b个星期c的日期。

提示:关于闰年的规则:年份是400的整数倍时是闰年,否则年份是4的倍数并且不是100的倍数时是闰年,其他年份都不是闰年。例如1900年就不是闰年,而2000年是闰年。

为了方便你推算,已知1850年1月1日是星期二。

Input Format

输入包含恰好一行,有五个整数a, b, c, y1, y2。其中c=1, 2, ……, 6, 7分别表示星期一、二、……、六、日。

Output Format

对于y1和y2之间的每一个年份,包括y1和y2,按照年份从小到大的顺序输出一行。

如果该年的a月第b个星期c确实存在,则以"yyyy/mm/dd"的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠“/”分隔,位数不足时前补零。

如果该年的a月第b个星期c并不存在,则输出"none"(不包含双引号)。

Sample Input

5 2 7 2014 2015

Sample Output

2014/05/11
2015/05/10

Limits

所有评测用例都满足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050。

FineArtz's solution

/* 节日计算器 */
#include <iostream>
#include <string>
using namespace std;

inline int succ(int x) { return ((x + 1) % 7 == 0) ? 7 : ((x + 1) % 7); }
inline string f(int x) {
    string ret = "";
    if (x / 10){
        ret += char(x / 10 + '0');
    }
    else ret += "0";
    ret += char(x % 10 + '0');
    return ret;
}
int main(){
    int date[205][15][35] = {0};
    date[0][1][1] = 2;
    for (int yy = 0; yy <= 2050 - 1850; ++yy){
        int day = 0, lday = 0, year = yy + 1850;
        for (int mm = 1; mm <= 12; ++mm)
        {
            switch(mm){
            case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                day = 31;
                break;
            case 4: case 6: case 9: case 11:
                day = 30;
                break;
            case 2:
                day = ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) ? 29 : 28;
                break;
            }
            if (mm > 1) date[yy][mm][1] = succ(date[yy][mm - 1][lday]);
            else if (yy != 0) date[yy][mm][1] = succ(date[yy - 1][12][31]);
            for (int dd = 2; dd <= day; ++dd)
                date[yy][mm][dd] = succ(date[yy][mm][dd - 1]);
            lday = day;
            day = 0;
        }
    }
    int a, b, c, y1, y2;
    cin >> a >> b >> c >> y1 >> y2;
    for (int yy = y1; yy <= y2; ++yy){
        int dd = 1, cnt = 0;
        while (date[yy - 1850][a][dd]){
            if (date[yy - 1850][a][dd] == c) ++cnt;
            if (cnt == b){
                cout << yy << "/" << f(a) << "/" << f(dd) << endl;
                break;
            }
            ++dd;
        }
        if (!date[yy - 1850][a][dd]) cout << "none" << endl;
    }
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
using namespace std;

int main() {
    int a, b, c, y1, y2;
    cin >> a >> b >> c >> y1 >> y2;
    --c;

    int months[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };

    for (int year = 1850, weekday = 1; year <= y2; ++year) {
        //判断是否是闰年
        bool is_year = false;
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            months[2] = 29;
            is_year = true;
        }
        else {
            months[2] = 28;
            is_year = false;
        }
        if(year<y1){
            if (is_year)
                weekday = (weekday + 2) % 7;
            else
                weekday = (weekday + 1) % 7;
            continue;
        }
        int cur_day = weekday;
        //计算月份
        for (int month = 1; month < a; ++month)
            cur_day = (cur_day + months[month] % 7) % 7;
        //计算第一个日期
        int first_date = (c + 7 - cur_day) % 7 + 1;
        int date = first_date + (b - 1) * 7;
        if (date <= months[a])
            printf("%d/%02d/%02d\n", year, a, date);
        else
            printf("none\n");

        //调整日期
        if (is_year)
            weekday = (weekday + 2) % 7;
        else
            weekday = (weekday + 1) % 7;
    }

    return 0;
}

q4x3's solution

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int mon, b, c, y1, y2;
    int t[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    cin >> mon >> b >> c >> y1 >> y2;
    int tmp = y1 - 1 - 1849;
    int one = 1 + tmp + tmp / 4;
    if (y1 - 1 >= 1901) -- one;
    one = one % 7;//y1 - 1年1.1的星期
    for (int i = y1;i <= y2;++ i) {
        bool flag = 0;
        if (i % 4 == 0 && i != 1900) t[1] = 29;
        one += 1;
        if ((i - 1) % 4 == 0 && i - 1 != 1900) ++ one;
        one %= 7;//i年1.1
        int monone = one;
        for (int j = 0;j < mon - 1;++ j) monone += t[j];
        monone %= 7;
        if (monone == 0) monone = 7;
        int b_c;
        if (c >= monone) {
            b_c = (b - 1) * 7 + 1 + c - monone;
        }
        if (c < monone) {
            int c1 = c + 7 - monone + 1;
            b_c = (b - 1) * 7 + c1;
        }
        if (b_c < 1 || b_c > t[mon - 1]) cout << "none" << endl;
        else {
            cout << i << '/';
            cout << setw(2) << setfill('0') << mon;
            cout << '/' << setw(2) << setfill('0') << b_c << endl;
        }
        t[1] = 28;
    }
}

skyzh's solution

#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    int a, b, c, y1, y2;
    cin >> a >> b >> c >> y1 >> y2;
    int y = 1850;
    int m = 1;
    int d = 0;
    int day = 1;
    int week = 1;
    int dom[] = {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int _dcnt[8] = { 0 };
    bool found = false;
    while (true) {
        ++d;
        ++day;
        int _dom = dom[m - 1];
        if (m == 2) {
            _dom = 28;
            if (y % 400 == 0 || y % 100 != 0 && y % 4 == 0) {
                _dom = 29;
            }
        }
        if (day > 7) {
            day = 1;
            ++week;
        }
        if (d > _dom) {
            d = 1;
            ++m;
            for (int i = 1; i <= 7; i++) _dcnt[i] = 0;
            week = 1;
        }
        if (m > 12) {
            m = 1;
            if (y1 <= y && y <= y2 && found == false) printf("none\n");
            ++y;
            found = false;
        }
        ++_dcnt[day];
        if (y1 <= y && y <= y2 && m == a && _dcnt[c] == b && day == c) {
            printf("%d/%02d/%02d\n", y, m, d);
            found = true;
        }
        if (y > y2) break;
    }
    return 0;
}

WashSwang's solution

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char cmd1[10],cmd2[10],s[1010000],ans[1010000];
int t,n,top,stack[1050000],vis[1010000];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void inorderEncode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            top--;
            ans[i++]=s[now-1];
            if (rs(now)<=n) stack[top++]=rs(now);
        }
    }
}
inline void preorderEncode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            ans[i++]=s[now-1];
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            vis[now]++;
            if (rs(now)<=n) stack[top++]=rs(now);
        }
        else
            top--;
    }
}
inline void postorderEncode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            vis[now]++;
            if (rs(now)<=n) stack[top++]=rs(now);
        }
        else
        {
            ans[i++]=s[now-1];
            top--;
        }
    }
}
inline void inorderDecode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            top--;
            ans[now-1]=s[i++];
            if (rs(now)<=n) stack[top++]=rs(now);
        }
    }
}
inline void preorderDecode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            ans[now-1]=s[i++];
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            vis[now]++;
            if (rs(now)<=n) stack[top++]=rs(now);
        }
        else
            top--;
    }
}
inline void postorderDecode(const char* s,int n){
    int i=0,now;
    stack[top++]=1;
    while (top!=0){
        now=stack[top-1];
        if (vis[now]==0){
            vis[now]++;
            if (ls(now)<=n) stack[top++]=ls(now);
        }
        else
        if (vis[now]==1){
            vis[now]++;
            if (rs(now)<=n) stack[top++]=rs(now);
        }
        else
        {
            ans[now-1]=s[i++];
            top--;
        }
    }
}
int main() {
    cin>>t;
    ios::sync_with_stdio(false);
    for (int i=0;i<t;++i){
        top=0;
        memset(ans,0,sizeof(ans));
        memset(vis,0,sizeof(vis));
        cin>>n>>cmd1>>cmd2>>s;
        if (strcmp(cmd1,"INORDER")==0){
            if (strcmp(cmd2,"ENCODE")==0)
                inorderEncode(s,n);
            else
                inorderDecode(s,n);
        }
        if (strcmp(cmd1,"PREORDER")==0){
            if (strcmp(cmd2,"ENCODE")==0)
                preorderEncode(s,n);
            else
                preorderDecode(s,n);
        }
        if (strcmp(cmd1,"POSTORDER")==0){
            if (strcmp(cmd2,"ENCODE")==0)
                postorderEncode(s,n);
            else
                postorderDecode(s,n);
        }
        cout<<ans<<endl;
    }
    return 0;
}

yyong119's solution

#include <iostream>
#include <vector>
#include <map>
#include <iomanip>
using namespace std;

bool isLeapYear(int year) {

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

int days(bool leap, int month) {

    switch (month) {
         case 1:
             return 0;
         case 2:
             return 31;
         case 3:
             return leap ? 60 : 59;
         case 4:
             return leap ? 91 : 90;
         case 5:
             return leap ? 121 : 120;
         case 6:
             return leap ? 152 : 151;
         case 7:
             return leap ? 182 : 181;
         case 8:
             return leap ? 213 : 212;
         case 9:
             return leap ? 244 : 243;
         case 10:
             return leap ? 274 : 273;
         case 11:
             return leap ? 305 : 304;
         case 12:
             return leap ? 335 : 334;
    }
}

int monthDays(bool leap, int month) {

     switch (month) {
         case 1:
         case 3:
         case 5:
         case 7:
         case 8:
         case 10:
         case 12:
             return 31;
         case 4:
         case 6:
         case 9:
         case 11:
         return 30;
         case 2:
             return leap ? 29 : 28;
    }
}

int main() {
    int month, week, day, year1, year2, leapCount(0);
    cin >> month >> week >> day >> year1 >> year2;
    for (int i = 1850; i < year1; i++)
        if (isLeapYear(i)) leapCount++;
    for (int i = year1; i <= year2; i++) {
        bool leap = isLeapYear(i);
        int totalDays = (i - 1850) * 365 + leapCount + days(leap, month);
        int weekDay = totalDays % 7 + 2;
        int weekCount = day < weekDay ? 1 : 2;
        int ans = 8 - weekDay + (week - weekCount) * 7 + day;
        if (ans <= monthDays(leap, month)) {
            cout << i << "/";
            if (month < 10)
                cout << 0;
            cout << month << "/";
            if (ans < 10)
                cout << 0;
            cout << ans << endl;
        }
        else cout << "none" << endl;
        if (leap) leapCount++;
    }
    return 0;
}