AcWing 1229. 日期问题 解题思路及代码

先贴个题目:

以及原题链接:1229. 日期问题 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/1231/

 这题其实和之前的回文日期相似,可以直接暴力枚举,然后得解,放个小片段:

for (int date = 19600101; date <= 20591231; date ++ )
    {
        int year = date / 10000, month = date % 10000 / 100, day = date % 100;
        if (check_valid(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)           
                printf("%d-%02d-%02d\n", year, month, day);
        }
    }

 然后我觉得计算不够方便,次数有点多,优化!其实这个题可以简化成纯暴力枚举判断是否合法,给大家看看我的原码:

#include <iostream>
#include <algorithm>
#include<cstring>
using namespace std;

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

bool operator<(Date &a, Date &b)
{
    if (a.year < b.year)
        return true;
    else if (a.year == b.year)
    {
        if (a.month < b.month)
            return true;
        else if (a.month == b.month)
        {
            if (a.day < b.day)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}

Date date[20];
bool legal[20];
int a[3], days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool check(int year)
{
    if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0)
        return true;
    else
        return false;
}
int main()
{
    memset(legal, true, sizeof(legal));
    int cnt = 0;
    scanf("%d/%d/%d", &a[0], &a[1], &a[2]);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 3; ++k)
            {
                int year = a[i], month = a[j], day = a[k];
                if (i == j || j == k || i == k || i == 1 || j == 2)
                    continue;
                if (year >= 60)
                    year += 1900;
                else
                    year += 2000;
                if (month < 1 || month > 12)
                    continue;
                if (month != 2)
                    if (day < 1 || day > days[month])
                        continue;
                if (month == 2 && check(year) == true)
                    if (day < 1 || day > 29)
                        continue;
                if (month == 2 && check(year) == false)
                    if (day < 1 || day > 28)
                        continue;
                date[cnt].year = year;
                date[cnt].month = month;
                date[cnt].day = day;
                cnt++;
            }
    sort(date, date + cnt);
    for (int i = 0; i < cnt - 1; ++i)
    {
        if (date[i].year == date[i + 1].year && date[i].month == date[i + 1].month && date[i].day == date[i + 1].day)
            legal[i] = false;
    }
    for (int i = 0; i < cnt; ++i)
        if (legal[i])
            printf("%d-%02d-%02d\n", date[i].year, date[i].month, date[i].day);
    return 0;
}

其实代码会稍微比纯暴力枚举长很多,但确实计算速度快,由于要按时间先后输出,创建结构体数组以及重载<和sort实现排序功能。以及注意不是每个位置的数都可以表示日月年,所以判断条件较为复杂。但yysy,写出来的感觉挺爽的()。

by———2024.2.28刷题记录

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值