枚举的一个思想

判断日期

https://www.acwing.com/problem/content/1231/

分析:

这个题的难点在于对于三个数,题目只要求输出三个序列, 按座标表示就是0 1 2, 1 2 0, 2 1 0

但是还得满足一个条件,就是输出的这三个序列还得按照从小到大的顺序输出 ,这就无法直接写输出语句输出,还得判断三个数的大小,给出一个比较笨的写法

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

int days[] = {0, 32, 29, 32, 31, 32, 31, 32, 32, 31, 32, 31, 32};

int main()
{
    int a[3];
    scanf("%d/%d/%d", &a[0], &a[1], &a[2]);
    bool d = a[0] < a[2];
    int year = d ? a[0] : a[2];
    int month = d ? a[1] : min(a[1], a[0]);
    int day = (a[0] + a[1] + a[2]) - year - month;
    if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
        cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;
    if(a[0] == a[1] && a[1] == a[2])return 0;
    if(!d)
    {
        if(month ^ day)
        {
            month ^= day ^= month;
            day ^= month;
            if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
                cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;

        }
        year = a[0], month = a[1], day = a[2];
        if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
            cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;
    }
    else
    {
        year = a[2];
        month = min(a[1], a[0]);
        day = (a[0] + a[1] + a[2]) - year - month;
        if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
            cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;
        if(month ^ day)
        {
            month ^= day ^= month;
            day ^= month;
            if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
                cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;

        }
    }
    return 0;
}

可以看到比较麻烦,判断语句还多,判断语句的条件更多,是一种比较费事的写法

改进

刚才提到,只有三种排列,所以可以直接枚举一下, 用一个整数表示,根据这三个数的大小再进行输出

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

int days[] = {0, 32, 29, 32, 31, 32, 31, 32, 32, 31, 32, 31, 32};

int main()
{
    int a[3];
    scanf("%d/%d/%d", &a[0], &a[1], &a[2]);
    int b[3] = {a[0] * 10000 + a[1] * 100 + a[2],
               a[2] * 10000 + a[1] * 100 + a[0],
               a[2] * 10000 + a[0] * 100 + a[1]};
    sort(b, b + 3);
    for(int i = 0; i < 3;  i ++)
    {
        if(i && (b[i] == b[i - 1]))continue;
        int year = b[i] / 10000;
        int month = b[i] % 10000 / 100;
        int day = b[i] % 100;
        if(day && month && month < 13 && (day < days[month] || (month == 2 && year % 4 == 0 && day < 30)))
            cout << (year > 59 ? 19 : 20) << year/10 << year % 10 << "-" << month / 10 << month % 10 << "-" << day / 10 << day % 10 << endl;
    }
    return 0;
}

可以看出,代码量显然不是一个量级的,并且只有两个判断,最多执行6次,而第一个代码执行了将近9次的代码,并且容易出错,出错很难修改。并且第一个代码运行时间是53ms,第二个是40ms。

因此,枚举题里面的枚举元素很复杂,并且有许多限制条件时,最好寻找一个简洁的载体用来承载

posted @ 2021-03-02 00:26  kanbujian55  阅读(51)  评论(0)    收藏  举报