zoukankan      html  css  js  c++  java
  • P7075

    题面

    分析

    听说可以用二分做,但是我直接模拟。

    最开始我先直接把所有的日子直接转换成儒略历。

    若转换后没有超过公元年,那么直接输出,结束

    若超过公元年,先给年号 (+1) (跳过 (0) 年),然后再判断:

    若没有超过 1582.10.5,直接输出。

    否则,给天数加上十天,然后开始补格里高利历与儒略历之间的差距:每 400 年 3 天的差距。

    补完之后输出就可以了。

    注意你需要对这个做法进行加速,不然会 TLE 10 pts。

    细节在代码里有。

    代码

    比较丑陋。考场上炸了 90 pts,因为第一次膜 (1461) 时没有特殊处理导致 day 直接等于 (0),直接爆炸。后来被官方数据又 hack 一个点,是中间的地方膜 (146097) 时没有特殊处理的原因。

    #include <bits/stdc++.h>
    using namespace std;
    
    template <typename T>
    T read(void) {
        T f = 1, num = 0;
        char c = getchar();
        while (c < '0' || c > '9') {
            if (c == '-') f = -f;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            num = (num << 3) + (num << 1) + (c ^ 48);
            c = getchar();
        }
        return f * num;
    }
    
    const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    inline int daysBefore(int year, int month) {  //儒略历天数
        if (month != 2) return days[month - 1];
        if ((year > 0 && year % 4 == 0) || (year < 0 && year % 4 == -1)) return 29;
        return 28;
    }
    inline int daysNear(int year, int month) {  //格里高利历天数
        if (month != 2) return days[month - 1];
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) return 29;
        return 28;
    }
    inline int daysInYear(int year) {  //格里高利历每年天数
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) return 366;
        return 365;
    }
    
    int main() {
        int Q = read<int>();
        while (Q--) {
            long long day = read<long long>();
            int year = -4713 + day / 1461 * 4, month = 1;
            //4年一个循环,4年天数共365*4+1=1461
            day %= 1461;
            day++;  //注意开始的时候是一月一号,所以要加一
            //公元年特判
            if (year >= 0) year++;
            //暴力弥补剩下的月份
            while (day > daysBefore(year, month)) {
                day -= daysBefore(year, month);
                if (++month == 13) month = 1, year++;
                if (year == 0) year++;
            }
            if (year < 0)  //公元前
                printf("%lld %d %d BC
    ", day, month, -year);
            else {
                if (year > 1582 || (year == 1582 && month > 10) || (year == 1582 && month == 10 && day > 4)) {
                    //如果超过了1582.10.4
                    day += 10;  //补上十天
                    //暴力处理月份
                    if (daysBefore(year, month) < day) {
                        day -= daysBefore(year, month);
                        if (++month == 13) month = 1, year++;
                    }
                    //每400年补上3天
                    long long plus = (year - 1600) / 400 * 3;
                    //暴力枚举不足400年的剩余部分
                    for (register int i = (year - 1600) / 400 * 400 + 1600; i < year || (i == year && month > 2); i += 100)
                        if (i % 400 != 0) plus++;
                    //加上
                    day += plus;
                    //先将没有满的年份补满
                    while (daysNear(year, month) < day) {
                        day -= daysNear(year, month);
                        if (++month == 13) {
                            month = 1, year++;
                            break;
                        }
                    }
                    //每400年一个轮回,400*365+100-4+1=146097天
                    day--, year += day / 146097 * 400, day %= 146097, day++;
                    while (daysInYear(year) < day) day -= daysInYear(year++);  //对于多余的年份加速处理
                    //处理剩余出的月份
                    while (daysNear(year, month) < day) {
                        day -= daysNear(year, month);
                        if (++month == 13) month = 1, year++;
                    }
                }
                printf("%lld %d %d
    ", day, month, year);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    002-html表格
    001-html常见的标记
    获取本地内外网ip地址
    Windows10设置默认简体美式键盘输入法
    C# 历史版本特性变更
    SQL Server Report Builder RDLC按记录数分页
    自动补全(备份)
    t:datagrid 行编辑 类型备份
    自动生成编号
    文本框上绑校验
  • 原文地址:https://www.cnblogs.com/macesuted/p/solution-P7075.html
Copyright © 2011-2022 走看看