[蓝桥杯刷题]---模拟法[2]日期问题

题目如下: 

[蓝桥杯刷题]---模拟法[2]日期问题_第1张图片 
题目的意思是:

给出一个日期(格式是yy mm dd,注意年份只有两位数),要找出所有可能的真实日期(合法的yyyy-mm-dd格式)。

需要考虑:

年份范围在1960到2059。

输入的yy、mm、dd可能互换,比如02 03 04可以是2002-03-04、2004-03-02、2003-02-04等等,三者顺序可以交换。

按日期从早到晚排序输出。

#include 
#include 

typedef struct {
    int year, month, day;
} Date;

// 判断是否是闰年
int isLeap(int year) {
    return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

// 判断日期是否合法
int isValidDate(int year, int month, int day) {
    if (year < 1960 || year > 2059) return 0;
    if (month < 1 || month > 12) return 0;
    int days_in_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    if (isLeap(year)) days_in_month[1] = 29;
    if (day < 1 || day > days_in_month[month - 1]) return 0;
    return 1;
}

// 比较函数用于排序
int cmp(const void *a, const void *b) {
    Date *d1 = (Date *)a;
    Date *d2 = (Date *)b;
    if (d1->year != d2->year) return d1->year - d2->year;
    if (d1->month != d2->month) return d1->month - d2->month;
    return d1->day - d2->day;
}

// 检查一个日期是否已经出现过
int isSame(Date *a, Date *b) {
    return a->year == b->year && a->month == b->month && a->day == b->day;
}

int main() {
    int a[3];
    scanf("%d%d%d", &a[0], &a[1], &a[2]);
    Date dates[6]; // 最多6种排列
    int count = 0;
    
    // 枚举所有排列
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (j == i) continue;
            for (int k = 0; k < 3; k++) {
                if (k == i || k == j) continue;
                int y = a[i], m = a[j], d = a[k];
                int year = (y >= 0 && y <= 59) ? (2000 + y) : (1900 + y);
                if (isValidDate(year, m, d)) {
                    Date newDate = {year, m, d};
                    int exist = 0;
                    for (int t = 0; t < count; t++) {
                        if (isSame(&dates[t], &newDate)) {
                            exist = 1;
                            break;
                        }
                    }
                    if (!exist) {
                        dates[count++] = newDate;
                    }
                }
            }
        }
    }
    
    // 排序
    qsort(dates, count, sizeof(Date), cmp);
    
    // 输出
    for (int i = 0; i < count; i++) {
        printf("%04d-%02d-%02d\n", dates[i].year, dates[i].month, dates[i].day);
    }
    
    return 0;
}

 程序解析

结构体Date

用来存储一个日期的年、月、日。

闰年判断

如果年份能被400整除,或者能被4整除但不能被100整除,就是闰年。

日期是否合法

年份必须在1960-2059之间。

月份必须在1-12之间。

天数必须不超过该月的最大天数(闰年2月是29天)。

排列所有可能情况

输入的3个数,可以组成3! = 6种不同的排列。

每一种排列都转成一个完整的yyyy-mm-dd格式,然后判断是否合法。

注意避免重复保存相同的日期。

排序输出

用qsort按照年-月-日顺序排序。

最后按标准格式输出,每个日期一行。

输入:

2 3 4 

可能的日期(按排列枚举):

2002-03-04 (合法)

2002-04-03 (合法)

2003-02-04 (合法)

2003-04-02 (合法)

2004-02-03 (合法)

2004-03-02 (合法)

排序后输出:

2002-03-04

2002-04-03

2003-02-04

2003-04-02

2004-02-03

2004-03-02 

运行截图:

[蓝桥杯刷题]---模拟法[2]日期问题_第2张图片

你可能感兴趣的:(蓝桥杯,算法,职场和发展)