枚举的一个思想
判断日期
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。
因此,枚举题里面的枚举元素很复杂,并且有许多限制条件时,最好寻找一个简洁的载体用来承载

浙公网安备 33010602011771号