求助
查看原帖
求助
175567
littlefrog楼主2020/11/21 12:01

70分,求大佬帮忙看看

#include <bits/stdc++.h>
using namespace std;
int yearr = 1582, monthh = 10, dayy = 15, dayys;
int perYear = 400;
#define int long long
struct Date {
	int year, month, day;

    inline void print() {
        if (year < 0) {
            printf("%lld %lld %lld BC\n", day, month, abs(year - 1));
        } else {
            printf("%lld %lld %lld\n", day, month, year);
        }
    }
	
	inline bool isLeap(int yy) {
		if (yy < yearr) {
			return yy % 4 == 0;
		}
		return yy % 400 == 0 || (yy % 4 == 0 && yy % 100 != 0);
	}
	
	inline int getMonthDays(int yy, int mm) {
        int ret;

		switch (mm) {
            case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                ret = 31;
                break;
            case 4: case 6: case 9: case 11:
                ret = 30;
                break;
            case 2 :
                if (isLeap(yy)) {
                    ret = 29;
                } else {
                    ret = 28;
                }
                break;

            default:
                assert(0);
        }

        if (yy == yearr && mm == 10) { // 对中间删除的日期单独处理
            ret -= 10;
        }

        return ret;
	}

    inline int getYearDays(int yy) {
        int ret = 365 + isLeap(yy);
        if (yy == 1582) { // 对中间删除的日期单独处理
            ret -= 10;
        }

        return ret;
    }

    inline int getJumpYearDays(int yy, int jumpyears) {
        int ret = 0;
        for (int i = 1; i <= jumpyears; ++i) {
            ret += getYearDays(yy + i);
        }

        return ret;
    }
};

int a[100001];
Date ans[100001];

inline bool cmp(int x, int y) {
    return a[x] < a[y];
}

inline void solve(int n, int a[], Date ans[]) {
    // BigJumpYear : 跳跃跨度400年
    // JumpYear : 跳跃跨度1年
    // JumpMonth : 跳跃跨度1个月

    int BigJumpYear, JumpYear, JumpMonth;
    int pos = 1; // 当前正在解决第几个询问
    int ctr = 0; // 当前是第几个儒略日
    int ord[100001]; // 各个询问从小到大排序后处理的顺序
    Date cur; // 当前结果

    BigJumpYear = cur.getJumpYearDays(yearr, perYear);

    for (int i = 1; i <= n; ++i) {
        ord[i] = i;
    }

    sort(ord + 1, ord + n + 1, cmp);
    
    for (cur.year = -4712; pos <= n; ++cur.year) { // 枚举年份 
        
        // 此处是从公元前4712年开始是因为公元前1、5、9、...、4713年是闰年,所以按照公元后的闰年规则反推前面就会差一个闰年,所以从4712年开始反推
        if (cur.year > yearr && ctr + BigJumpYear <= a[ord[pos]]) { // 
            cur.year += perYear;
            cur.year--; // 由于for循环判断是只要pos != n 就自动再让cur.year + 1,所以这里要减去1,下面几处也是同理
            ctr += BigJumpYear;
            continue ;
        }

        JumpYear = cur.getYearDays(cur.year);

        if (ctr + JumpYear <= a[ord[pos]]) {
            ctr += JumpYear;
            continue ;
        }

        for (cur.month = 1; cur.month <= 12; ++cur.month) { // 枚举月份
            JumpMonth = cur.getMonthDays(cur.year, cur.month);

            if (ctr + JumpMonth <= a[ord[pos]]) {
                ctr += JumpMonth;
                continue ;
            }

            bool flag;

            if (JumpMonth == 21) { // 由于中间跳过了10天,所以1582年10月只有21天,这里使用一个标记判定这种情况
                flag = 1;
            } else {
                flag = 0;
            }

            for (cur.day = 1; cur.day <= JumpMonth; ++cur.day) { // 枚举天数
                while (ctr == a[ord[pos]] && pos <= n) {
                    ans[ord[pos]].year = cur.year;
                    ans[ord[pos]].month = cur.month;
                    ans[ord[pos]].day = cur.day;
                    pos++;
                }

                ctr++;

                if (cur.day == 4 && flag) {
                    cur.day = 14;
                }
            }
        }
    }
}

signed main() {
	freopen("bibi.in", "r", stdin);
	freopen("bibi.out", "w", stdout); 
	
	int Q;
	scanf("%lld", &Q);
	
	for (int i = 1; i <= Q; ++i) {
		scanf("%lld", &a[i]);
	}

    solve(Q, a, ans);

    for (int i = 1; i <= Q; ++i) {
        ans[i].print();
    }
}
2020/11/21 12:01
加载中...