ZOJ - 3950 How Many Nines 年份大模拟

大模拟


大体思路:

给定 y1:m1:d1 ~ y2:m2:d2,

可以分为三个阶段,分别计算:

① y1+1 ~ y2-1  这其中的整年份可以直接算出来:打表预处理

② y1:m1:d1 ~ y1年年末;  多少个月,多少天,分别考虑

③ y2年年初 ~ y2:m2:d2; ==


闰年的关系处理清楚就行了;


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100 + 7, maxd = 1e8;
const ll mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;


int n1[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int n2[15] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int sum[10000];

bool is_run(int n) {
    if( (n % 4 == 0 && n % 100 != 0) || (n % 400 == 0)) return true;
    else return false;
}

int num_(int n) {
    int cnt = 0;
    while(n) {
        int t = n % 10;
        if(t == 9) cnt++;
        n /= 10;
    }
    return cnt;
}

void init() {
    sum[1999] = 0;
    for (int i = 2000; i <= 9999; i ++) {
        if (is_run(i)) {
            sum[i] = sum[i-1] + ( 36 + 366*num_(i) + 30);
        } else {
            sum[i] = sum[i-1] + (35 + 365*num_(i) + 30);
        }
    }
}


int main() {

    int n;
    int y1, m1, d1, y2, m2, d2;
    init();

    scanf("%d", &n);
    for(int ii = 0; ii < n; ++ii) {
        int ans = 0;
        scanf("%d %d %d %d %d %d", &y1, &m1, &d1, &y2, &m2, &d2);
        ans += max(0, (sum[y2-1] - sum[y1]));
        int tt1 = 0, tt2 = 0;
        if(is_run(y1)) {
            int t1 = num_(y1);
            int t2 = 0;
            for(int i = 1; i < m1; ++i)
                t2 += (n2[i]);
            int t3 = (366 - t2 - d1+1) * t1; // 年 贡献
            int t4 = (12 - m1)*3;
            int t5 = 0;
            for(int i = d1; i <= 30; ++i) { // 日 贡献
                if(i % 10 == 9) t5 ++;
            }
            int t6 = 0;
            if(m1 == 9) {
                t6 += (30 - d1 + 1);
            } else if(m1 < 9) {
                t6 += (30);
            }
            tt1 = (t3 + t4+t5 + t6);
        } else {
            int t1 = num_(y1);
            int t2 = 0;
            for(int i = 1; i < m1; ++i)
                t2 += (n1[i]);
            int t3 = (365 - t2 - d1+1) * t1; // 年 贡献
            int t4 = (12 - m1)*3;
            int t5 = 0;
            for(int i = d1; i <= 30; ++i) { // 日 贡献
                if(i % 10 == 9) t5 ++;
            }
            if(m1 <= 2) t5--;

            int t6 = 0;
            if(m1 == 9) {
                t6 += (30 - d1 + 1); // 月 贡献
            } else if(m1 < 9) {
                t6 += (30);
            }
            tt1 = (t3 + t4+t5 + t6);
        }

        if(is_run(y2)) {
            int t1 = num_(y2);
            int t2 = 0;
            for(int i = 1; i < m2; ++i)
                t2 += (n2[i]);
            int t3 = (t2 + d2) * t1;  // 年

            int t4 = (m2 - 1) * 3;
            int t5 = 0;
            for(int i = 1; i <= d2; ++i)
                if(i % 10 == 9) t5 ++;

            int t6 = 0;
            if(m2 > 9) {
                t6 += 30;
            } else if(m2 == 9) {
                t6 += (d2);
            }
            tt2 = (t3 + t4+t5 + t6);
        } else {
            int t1 = num_(y2);
            int t2 = 0;
            for(int i = 1; i < m2; ++i)
                t2 += (n1[i]);
            int t3 = (t2 + d2) * t1;  // 年

            int t4 = (m2 - 1) * 3;
            int t5 = 0;
            for(int i = 1; i <= d2; ++i)
                if(i % 10 == 9) t5 ++;
            if(m2 > 2) {
                t5--;
            }
            int t6 = 0;
            if(m2 > 9) {
                t6 += 30;
            } else if(m2 == 9) {
                t6 += (d2);
            }
            tt2 = (t3 + t4+t5 + t6);
        }

        if(y1 == y2) {

            int tt3 = 0;
            if(is_run(y1)) {
                tt3 = ( 36 + 366*num_(y1) + 30);
            } else tt3 = ( 35 + 365*num_(y1) + 30);

            ans += (tt2 + tt1 - tt3);
        } else {
            ans += (tt1 + tt2);
        }
        printf("%d\n", ans);
    }

    return 0;
}















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值