蓝桥杯练习题——日期问题

1.日期差值

思路

分别计算从第一年到两个日期过了多少天,然后相减

cpp 复制代码
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int x1, x2;

int f(int year, int month, int day){
    int res = 0;
    for(int y = 1; y < year; y++){
        if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[1] = 29;
        else a[1] = 28;
        for(int m = 1; m <= 12; m++){
            res += a[m - 1];
        }
    }
    if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) a[1] = 29;
    else a[1] = 28;
    for(int m = 1; m < month; m++){
        res += a[m - 1];
    }
    res += day;
    return res;
}

int main(){
    while(cin>>x1>>x2){
        int year1 = 0, month1 = 0, day1 = 0, year2 = 0, month2 = 0, day2 = 0;
        for(int i = 0; i < 2; i++){
            day1 = day1 + x1 % 10 * pow(10, i);
            day2 = day2 + x2 % 10 * pow(10, i);
            x1 /= 10, x2 /= 10;
        }
        for(int i = 0; i < 2; i++){
            month1 = month1 + x1 % 10 * pow(10, i);
            month2 = month2 + x2 % 10 * pow(10, i);
            x1 /= 10, x2 /= 10;
        }
        for(int i = 0; i < 4; i++){
            year1 = year1 + x1 % 10 * pow(10, i);
            year2 = year2 + x2 % 10 * pow(10, i);
            x1 /= 10, x2 /= 10;
        }
        //cout<<year1<<" "<<month1<<" "<<day1<<endl;
        int res1 = f(year1, month1, day1);
        int res2 = f(year2, month2, day2);
        cout<<abs(res1 - res2) + 1<<endl;
    }
    return 0;
}

// 或者简化
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int x1, x2;

int f(int year, int month, int day){
    int res = 0;
    for(int y = 1; y < year; y++){
        if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[1] = 29;
        else a[1] = 28;
        for(int m = 1; m <= 12; m++){
            res += a[m - 1];
        }
    }
    if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) a[1] = 29;
    else a[1] = 28;
    for(int m = 1; m < month; m++){
        res += a[m - 1];
    }
    res += day;
    return res;
}

int main(){
    int year1, month1, day1, year2, month2, day2;
    while(scanf("%04d%02d%02d", &year1, &month1, &day1) != -1){
        scanf("%04d%02d%02d", &year2, &month2, &day2);
        //cout<<year1<<" "<<month1<<" "<<day1<<endl;
        int res1 = f(year1, month1, day1);
        int res2 = f(year2, month2, day2);
        cout<<abs(res1 - res2) + 1<<endl;
    }
    return 0;
}

// 最简化
#include<iostream>
#include<cmath>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int f1(int year){
    return (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0));
}

int f2(int year, int month){
    if(month == 2) return 28 + f1(year);
    else return a[month];
}

int f3(int year, int month, int day){
    int res = 0;
    for(int i = 1; i < year; i++) res += 365 + f1(i);
    for(int i = 1; i < month; i++) res += f2(year, i);
    res += day;
    return res;
}

int main(){
    int year1, month1, day1, year2, month2, day2;
    while(scanf("%04d%02d%02d", &year1, &month1, &day1) != -1){
        scanf("%04d%02d%02d", &year2, &month2, &day2);
        int res1 = f3(year1, month1, day1);
        int res2 = f3(year2, month2, day2);
        cout<<abs(res1 - res2) + 1<<endl;
    }
    return 0;
}

2.日期问题


思路

按顺序枚举年月日,判断每一种情况

cpp 复制代码
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int check(int year, int month, int day){
    if(month == 0 || month > 12) return 0;
    if(day == 0) return 0;
    if(month == 2){
        int x = year % 400 == 0 || (year % 4 == 0 && year % 100);
        if(day > a[month] + x) return 0;
    }else{
        if(day > a[month]) return 0;
    }
    return 1;
}

int main(){
    int a, b, c;
    scanf("%2d/%2d/%2d", &a, &b, &c);
    int year, month, day;
    for(int i = 19600101; i <= 20591231; i++){
        year = i / 10000, month = i % 10000 / 100, day = i % 100;
        if(check(year, month, day)){
            if((year % 100 == a && month == b && day == c) || //年月日
               (month == a && day == b && year % 100 == c) || //月日年
               (day == a && month == b && year % 100 == c)){  //日月年
                // 前导补 0
                printf("%d-%02d-%02d\n", year, month, day);
            }
        }
    }
    return 0;
}

3.回文日期

思路

1.枚举每年每月每日,超时

2.因为回文串对称,所以只需要枚举前四位,判断符不符合

cpp 复制代码
// 超时
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int check1(int year, int month, int day){
    if(month == 0 || month > 12) return 0;
    if(day == 0) return 0;
    if(month == 2){
        int x = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
        if(day > a[month] + x) return 0;
    }else{
        if(day > a[month]) return 0;
    }
    return 1;
}

int check2(int x){
    string s = to_string(x);
    for(int i = 0, j = s.size() - 1; i < j; i++, j--){
        if(s[i] != s[j]) return 0;
    }
    return 1;
}

int main(){
    int a, b;
    scanf("%d%d", &a, &b);
    int cnt = 0;
    for(int i = a; i <= b; i++){
        int year = i / 10000, month = i % 10000 / 100, day = i % 100;
        if(check1(year, month, day) && check2(i)) cnt++;
    }
    printf("%d", cnt);
    return 0;
}

// 用点脑子
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int date1, date2;

int check1(int year, int month, int day){
    if(month == 0 || month > 12) return 0;
    if(day == 0) return 0;
    if(month == 2){
        int x = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
        if(day > a[month] + x) return 0;
    }else{
        if(day > a[month]) return 0;
    }
    return 1;
}

int check2(int x){
    if(x >= date1 && x <= date2) return 1;
    else return 0;
}

int main(){
    scanf("%d%d", &date1, &date2);
    int cnt = 0;
    int year, month, day;
    for(int i = 1000; i <= 9999; i++){
        int t = i, x = 0;
        for(int i = 0; i < 4; i++){
            x = x * 10 + t % 10;
            t /= 10;
        }
        year = i, month = x / 100, day = x % 100;
        if(check1(year, month, day) && check2(i * 10000 + x)) cnt++;
    }
    printf("%d", cnt);
    return 0;
}

4.日期计算


思路

累减每个月的天数,直到不够

cpp 复制代码
#include<iostream>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main(){
    int y, d;
    cin>>y>>d;
    if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) a[2] = 29;
    int cnt = 1;
    while(d > a[cnt]){
        d -= a[cnt];
        cnt++;
    }
    cout<<cnt<<endl;
    cout<<d;
    return 0;
}

5.回文日期


思路

先判断回文,再判断 AB 型

cpp 复制代码
#include<iostream>
#include<cstdio>
using namespace std;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool f1(int y){
    return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}

int f2(int y, int m){
    if(m == 2 && f1(y)) return 29;
    return a[m];
}

int main()
{
    int year, month, day;
    scanf("%04d%02d%02d", &year, &month, &day);
    bool flag = false;
    //每年只有一个回文日期  枚举年份
    for(int i = year; ; i++){
        //构造回文日期
        int x = i, res = 0;
        while(x){
            res = res * 10 + x % 10;
            x /= 10;
        }
        res += i * 10000;

        //判断合法性
        if(i == year && res <= year * 10000 + month * 100 + day) continue;
        int m = res % 10000 / 100, d = res % 100;
        if(m >= 1 && m <= 12 && d >= 1 && d <= f2(i, m)){
            if(!flag)
            {
                printf("%04d%02d%02d\n", i, m, d);
                flag = true;
            }
            if(m == d && d % 10 != d / 10)
            {
                printf("%04d%02d%02d\n", i, m, d);
                break;
            }
        }
    }
}
相关推荐
yuuki2332336 小时前
【C++】类和对象(上)
c++·后端·算法
dangdang___go6 小时前
动态内存管理||malloc和free.realloc和calloc
c语言·开发语言·算法·动态内存管理
数字化脑洞实验室6 小时前
智能决策与决策优化:从算法到产业的演进逻辑
算法
cpp_25016 小时前
P5412 [YNOI2019] 排队
数据结构·c++·算法·题解·洛谷
kingmax542120087 小时前
图论核心算法(C++):包括存储结构、核心思路、速记口诀以及学习方法, 一站式上机考试学习【附PKU百练,相关练习题单】
c++·算法·图论·信奥赛·上机考试·百练·pku
罗湖老棍子7 小时前
【例9.15】潜水员(信息学奥赛一本通- P1271)
c++·算法·动态规划·二维费用背包
_OP_CHEN7 小时前
算法基础篇:(二十一)数据结构之单调栈:从原理到实战,玩转高效解题
数据结构·算法·蓝桥杯·单调栈·算法竞赛·acm/icpc
q***51898 小时前
【语义分割】12个主流算法架构介绍、数据集推荐、总结、挑战和未来发展
算法·架构
Ghost-Silver8 小时前
《星火》——关于Deepseek的进化速度
笔记·算法
代码游侠12 小时前
日历的各种C语言实现方法
c语言·开发语言·学习·算法