[NOIP2016 普及组] 回文日期

[NOIP2016 普及组] 回文日期

题目背景

NOIP2016 普及组 T2

题目描述

在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。

牛牛习惯用 8 位数字表示一个日期,其中,前 4 位代表年份,接下来 2 位代表月份,最后 2 位代表日期。显然:一个日期只有一种表示方法,而两个不同的日期的表 示方法不会相同。

牛牛认为,一个日期是回文的,当且仅当表示这个日期的 8 位数字是回文的。现在,牛牛想知道:在他指定的两个日期之间包含这两个日期本身),有多少个真实存在的日期是回文的。

一个 8 位数字是回文的,当且仅当对于所有的 i1i8)从左向右数的第 i 个数字和第 9i 个数字(即从右向左数的第 i 个数字)是相同的。

例如:

  • 对于 2016 年 11 月 19 日,用 8 位数字 20161119 表示,它不是回文的。
  • 对于 2010 年 1 月 2 日,用 8 位数字 20100102 表示,它是回文的。
  • 对于 2010 年 10 月 2 日,用 8 位数字 20101002 表示,它不是回文的。

每一年中都有 12 个月份:

其中,1,3,5,7,8,10,12 月每个月有 31 天;4,6,9,11 月每个月有 30 天;而对于 2 月,闰年时有 29 天,平年时有 28 天。

一个年份是闰年当且仅当它满足下列两种情况其中的一种:

  1. 这个年份是 4 的整数倍,但不是 100 的整数倍;
  2. 这个年份是 400 的整数倍。

例如:

  • 以下几个年份都是闰年:2000,2012,2016
  • 以下几个年份是平年:1900,2011,2014

输入格式

两行,每行包括一个 8 位数字。

第一行表示牛牛指定的起始日期。

第二行表示牛牛指定的终止日期。

保证 date1date2 都是真实存在的日期,且年份部分一定为 4 位数字,且首位数字不为 0

保证 date1 一定不晚于 date2

输出格式

一个整数,表示在 date1date2 之间,有多少个日期是回文的。

样例 #1

样例输入 #1

20110101
20111231

样例输出 #1

1

样例 #2

样例输入 #2

20000101
20101231

样例输出 #2

2

样例 #3

样例输入 #3

20211202
20211202

样例输出 #3

1

样例 #4

样例输入 #4

40110123
98900301

样例输出 #5

214

提示

【样例说明】

对于样例 1,符合条件的日期是 20111102

对于样例 2,符合条件的日期是 2001100220100102

【子任务】

对于 60% 的数据,满足 date1=date2

solve

code

#include <bits/stdc++.h>
// #define ONLINE_JUDGE
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define SZ(v) ((int)v.size())
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef double db;
using namespace std;

int d[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int yr1, yr2, m1, m2, d1, d2;
int cnt;

bool check() {
    if(yr1 == yr2 && m1 == m2 && d1 == d2) return true;
    return false;
}

bool huiwen(int a, int b, int c) {
    int x = a * 10000 + b * 100 + c;
    int t = 0;
    string s = to_string(x);
    while(a) {
        a /= 10;
        t++;
    }    
    for(int i = 0; i < 4-t; i++) s = "0" + s;
    for(int i = 0, j = SZ(s)-1; i < j; i++, j--) {
        if(s[i] != s[j]) return false;
    }
    return true;
}

void run(int y) {
    if((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) d[2] = 29;
    else d[2] = 28;
}

void f() {
    ++d1;
    if(d1 > d[m1]) {
        d1 = 1;
        ++m1;
        if(m1 > 12) {
            yr1++;
            m1 = 1;
            run(yr1);
        }
    }
}

void ff() {
    ++d2;
    if(d2 > d[m2]) {
        d2 = 1;
        ++m2;
        if(m2 > 12) {
            yr2++;
            m2 = 1;
        }
    }
}


void solve() {
    string a, b;
    cin >> a >> b;
    yr1 = (a[0]-'0') * 1000 + (a[1]-'0') * 100 + (a[2]-'0')*10+ (a[3]-'0');
    yr2 = (b[0]-'0') * 1000 + (b[1]-'0') * 100 + (b[2]-'0')*10+ (b[3]-'0');
    m1 = (a[4]-'0') * 10 + (a[5]-'0');
    m2 = (b[4]-'0')*10+ (b[5]-'0');
    d1 = (a[6]-'0')*10+ (a[7]-'0');
    d2 = (b[6]-'0')*10+ (b[7]-'0');
    run(yr1);
    ff();
    while(!check()){
        if(huiwen(yr1, m1, d1)) {
            cnt++;
        }
        f();
    }
    cout << cnt << "\n";
}

int main() {
    FAST;       
    solve();
    return 0;
}
posted @   zhyyyyy115  阅读(165)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示