首页 > 试题广场 >

回文日期

[编程题]回文日期
  • 热度指数:1736 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}一个日期用 \sf YYYYMMDD8 位数字表示,其中前四位为年份,接着两位为月份,最后两位为日期。

\hspace{15pt}若这 8 位数字本身是一个回文数,则称该日期为回文日期

\hspace{15pt}给定起始日期 a 与终止日期 b(均包含在内,且满足 a\leqq b),请计算区间内真实存在的回文日期数量。

\hspace{15pt}【名词解释】回文数:一个数字从左往右读与从右往左读完全相同。

\hspace{15pt}【日期合法性】
\hspace{23pt}\bullet\, 1,3,5,7,8,10,12 月有 31 天;
\hspace{23pt}\bullet\, 4,6,9,11 月有 30 天;
\hspace{23pt}\bullet\, 2 月在闰年29 天,平年有 28 天。

\hspace{15pt}【闰年判定】
\hspace{23pt}\bullet\, 能被 4 整除但不能被 100 整除的年份;
\hspace{23pt}\bullet\, 或能被 400 整除的年份。

输入描述:
\hspace{15pt}第一行输入 8 位整数 a,表示起始日期。
\hspace{15pt}第二行输入 8 位整数 b,表示终止日期。


输出描述:
\hspace{15pt}输出一个整数,表示 [a,b] 区间内回文日期的数量。
示例1

输入

20110101
20111231

输出

1

说明

\hspace{15pt}在这个样例中,在 \sf{20110101}\sf{20111231} 之间,回文日期有 1 个,即 \sf{20111102}
示例2

输入

20000101
20101231

输出

2

说明

\hspace{15pt}在这个样例中,在 \sf{20000101}\sf{20101231} 之间,回文日期有 2 个,即 \sf{20010002}\sf{20100102}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt(); // 起始日期
        int b = scanner.nextInt(); // 终止日期
        scanner.close();
        
        int count = 0;
        
        // 遍历所有可能的回文日期
        // 8位回文日期的特点:前4位与后4位对称,如20211202
        // 因此只需遍历前4位,后4位由前4位反转得到
        int startYear = a / 10000;
        int endYear = b / 10000;
        
        for (int year = startYear; year <= endYear; year++) {
            // 生成回文日期
            int palindromeDate = generatePalindromeDate(year);
            
            // 检查是否在区间内
            if (palindromeDate >= a && palindromeDate <= b) {
                // 检查日期是否合法
                if (isValidDate(palindromeDate)) {
                    count++;
                }
            }
        }
        
        System.out.println(count);
    }
    
    /**
     * 根据年份生成可能的回文日期
     * 例如:年份2021,生成回文日期20211202
     */
    private static int generatePalindromeDate(int year) {
        // 将年份转为字符串
        String yearStr = String.format("%04d", year);
        // 反转年份字符串得到日期部分
        String reversedYear = new StringBuilder(yearStr).reverse().toString();
        // 组合成8位回文日期
        return Integer.parseInt(yearStr + reversedYear);
    }
    
    /**
     * 检查日期是否合法
     */
    private static boolean isValidDate(int date) {
        // 解析年、月、日
        int year = date / 10000;
        int month = (date % 10000) / 100;
        int day = date % 100;
        
        // 检查月份合法性
        if (month < 1 || month > 12) {
            return false;
        }
        
        // 检查日期合法性
        if (day < 1) {
            return false;
        }
        
        // 大月有31天
        if (month == 1 || month == 3 || month == 5 || month == 7 
            || month == 8 || month == 10 || month == 12) {
            return day <= 31;
        }
        // 小月有30天
        else if (month == 4 || month == 6 || month == 9 || month == 11) {
            return day <= 30;
        }
        // 2月,考虑闰年
        else { // month == 2
            if (isLeapYear(year)) {
                return day <= 29;
            } else {
                return day <= 28;
            }
        }
    }
    
    /**
     * 判断是否为闰年
     * 能被4整除但不能被100整除,或能被400整除的年份是闰年
     */
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
}

发表于 2025-08-29 11:04:36 回复(0)

代码中要加上下面这个才能运行成功,否则顺序遍历日期的这种方***超时。

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

bool iss(string s) {
    string c = s;
    reverse(c.begin(), c.end());
    return s == c;
}


int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    string a, b;
    cin >> a >> b;
    int c = 0;
    vector<int> mpa(13);

    int ya = stoi(a.substr(0, 4));
    int ma = stoi(a.substr(4, 2));
    int da = stoi(a.substr(6, 2));

    int yb = stoi(b.substr(0, 4));
    int mb = stoi(b.substr(4, 2));
    int db = stoi(b.substr(6, 2));
    int fm = 0, fd = 0, endm = 0, endd;

    int m, d;

    for (int y = ya; y <= yb; y++) {

        if ((y % 4 == 0 && y % 100 != 0 ) || y % 400 == 0) {
            mpa = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        } else {
            mpa = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        }

        if (fm == 0) {
            m = ma;
            fm = 1;
        } else {
            m = 1;
        }

        if (y == yb) endm = mb;
        else endm = 12;

        for (; m <= endm; m++) {

            if (fd == 0) {
                d = da;
                fd = 1;
            } else {
                d = 1;
            }

            for (; d <= mpa[m]; d++) {
                string ys = to_string(y);
                ys = string(4 - ys.size(), '0') + ys;
                string ms = m < 10 ? "0" + to_string(m) : to_string(m);
                string ds = d < 10 ? "0" + to_string(d) : to_string(d);
                if (iss(ys + ms + ds)) {
                    c++;
                }

            }

        }
    }
    cout << c;

}
发表于 2025-08-05 18:00:09 回复(0)
谁家好人输入9890年啊???我服了
发表于 2025-07-25 17:56:42 回复(0)
#include <stdio.h>
#include <stdlib.h>
typedef struct{
    int year;
    int month;
    int day;
    int max_day;//最大日期
}date;

//初始化并判断天数
void InitMonth (date* L){
    for(int i = 0;i < 12;i++){
        int m = L->month;
        if (m == 4 || m == 6 || m == 9 || m == 11){
            L->max_day = 30;//小月
        } else if (m == 02){
            if ((L->year%4 == 0 && L->year%100 != 0) || (L->year%400 == 0)){
                L->max_day = 29;//闰月
            } else {
                L->max_day = 28;//平月
            }
        } else {
            L->max_day = 31;//大月
        }
    }   
}
//将八位数转换为日期
void Date (int num, date* L){
    L->year = num / 10000;      
    int rem = num % 10000;
    L->month = rem / 100;    
    L->day = rem % 100;
}
//遍历日期
void NextDay(date* L) {
    L->day++;
    InitMonth(L);
    if (L->day > L->max_day){
        L->day = 1;
        L->month++;
        if (L->month >12){
            L->month = 1;
            L->year++;
        }
    }
}
//判断八位数上的数字是否对应,如20111102->2,0,1,1 ,1,1 ,0,2
int If_HuiwenDate (date L){
    int Y1 = L.year/1000;
    int Y2 = (L.year/100)%10;
    int Y3 = (L.year/10)%10;
    int Y4 = L.year%10;
    int M1 = L.month/10;
    int M2 = L.month%10;
    int D1 = L.day/10;
    int D2 = L.day%10;
    return (Y1 == D2) && (Y2 == D1) && (Y3 == M2) && (Y4 == M1);
}
//判断遍历时有没有超过终止日期
int Equal (date a, date b){
    if (a.year < b.year) return 1;
    if (a.year > b.year) return 0;
    if (a.month < b.month)  return 1;
    if (a.month < b.month)  return 0;
    return (a.day <= b.day);
}
int main() {
    int start, stop;
    scanf("%d",&start);
    scanf("%d",&stop);
    date s1, s2;
    Date (start, &s1);
    Date (stop, &s2);
    InitMonth(&s1);
    InitMonth(&s2);
    date s_final = s1;
    int count = 0;
    while (Equal(s_final, s2)){
        if(If_HuiwenDate(s_final)){
            count++;
        }
        NextDay(&s_final);
    }
    printf("%d", count);
    return 0;
}

发表于 今天 16:54:38 回复(0)

c++萌新写出来的暴力解法,还请各位dalao多多包涵

#include <iostream>
using namespace std;

int main() {
    int begin, end;
    cin >> begin >> end;
    // 分离起始年月日
    int y1 = begin / 10000;
    int m1 = begin / 100 % 100;
    int d1 = begin % 100;
    int y2 = end / 10000;
    int m2 = end / 100 % 100;
    int d2 = end % 100;

    int count = 0;
    // 遍历年数,生成回文日期
    for(int yy = y1;yy <= y2;yy++) {
        int mm = yy % 10 * 10 + yy / 10 % 10;
        int dd = yy / 100 % 10 * 10 + yy / 1000;
        // 判断日期是否合法
        if((yy == y1 && mm < m1) || (yy == y2 && mm > y2) || mm < 1 || mm > 12 || (yy == y1 && mm == m1 && dd < d1) || (yy == y2 && mm == m2 && dd > d2) || dd < 1 || dd > 31 ||(mm == 4 && dd > 30)||(mm == 6 && dd > 30)||(mm == 9 && dd > 30)||(mm == 11 && dd > 30) || (mm == 2 && dd > 29) || (mm == 2 && !(yy % 400 == 0 || yy % 4 == 0 && yy % 100 != 0) && dd > 28)) {
            continue;
        }
        count++;
    }
    cout << count << endl;
}
发表于 今天 12:37:24 回复(0)

def is_runnian(year):
    if (year%4 == 0 and year%100 != 0) or year%400 == 0:
        return True
    else:
        return False

def is_valid(y,m,d):
    if int(m)<=0 or int(m)>12:
        return False
    day = [31,28,31,30,31,30,31,31,30,31,30,31]
    if is_runnian(int(y)):
        day[1] = 29
    if int(d) > day[int(m)-1]:
        return False
    return True
   

start = input()
ys = start[0:4]
end = input()
ye = end[0:4]
cont = 0
for i in range(int(ys),int(ye)+1): #9220
    year = str(i).zfill(4)
    strs = year[::-1] #0229
    month,day = strs[:2],strs[2:]
    if is_valid(year,month,day):
        cont += 1
print(cont)

发表于 2025-09-24 21:23:25 回复(0)
def is_runyear(x):
    if (x%4==0 and x%100!=0) or x%400==0:
        return True
    return False
days_of_month = [31,28,31,30,31,30,31,31,30,31,30,31]
a = input()
b = input()
year_a = int(a[0:4])
year_b = int(b[0:4])
month_start = int(a[4:6])
month_end = int(b[4:6])
day_start = int(a[6:8])
day_end = int(b[6:8])
count = 0
for year in range(year_a,year_b+1):
    reverse_year = str(year)[::-1]
    month = int(reverse_year[0:2])
    day = int(reverse_year[2:4])
    if year_a<year<year_b:
        if month==2:
            if is_runyear(year) and 1<=day<=29:
                count += 1
            elif not is_runyear(year) and 1<=day<=28:
                count += 1
        elif 1<=month<=12 and 1<=day<=days_of_month[month-1]:
            count += 1
    elif year_a==year<year_b:
        if month>month_start:
            if month==2:
                if is_runyear(year) and 1<=day<=29:
                    count += 1
                elif not is_runyear(year) and 1<=day<=28:
                    count += 1
            elif 1<=month<=12 and 1<=day<=days_of_month[month-1]:
                count += 1
        elif month==month_start:
            if month==2:
                if is_runyear(year) and day_start<=day<=29:
                    count += 1
                elif not is_runyear(year) and day_start<=day<=28:
                    count += 1
            elif 1<=month<=12 and day_start<=day<=days_of_month[month-1]:
                count += 1
    elif year_a<year==year_b:
        if month<month_end:
            if month==2:
                if is_runyear(year) and 1<=day<=29:
                    count += 1
                elif not is_runyear(year) and 1<=day<=28:
                    count += 1
            elif 1<=month<=12 and 1<=day<=days_of_month[month-1]:
                count += 1
        elif month==month_end:
            if 1<=day<=day_end:
                count += 1
    elif year_a==year==year_b:
        if month_start<month<month_end:
            if month==2:
                if is_runyear(year) and 1<=day<=29:
                    count += 1
                elif not is_runyear(year) and 1<=day<=28:
                    count += 1
            elif 1<=month<=12 and 1<=day<=days_of_month[month-1]:
                count += 1
        elif month_start==month<month_end:
            if month==2:
                if is_runyear(year) and day_start<=day<=29:
                    count += 1
                elif not is_runyear(year) and day_start<=day<=28:
                    count += 1
            elif 1<=month<=12 and day_start<=day<=days_of_month[month-1]:
                count += 1
        elif month_start<month==month_end:
            if 1<=day<=day_end:
                count += 1
        elif month_start==month==month_end:
            if day_start<=day<=day_end:
                count += 1

print(count)
发表于 2025-08-25 17:51:57 回复(0)