洛谷 P2010 【回文日期】题解
思路:模拟、枚举
这道题是 NOIP2016 PJ T2,作为普及组的第二题,我认为它对于普及组选手来说还是有一些难度的。
我没有想到 @「QQ红包」 管理员大佬那样枚举月日的 $ O(N^2) $ 做法,写成了三重循环,枚举年月日,然后再判断是否回文。然后就成为了最差解(
主要注释在代码中。
$ \rm code $
# include <bits/stdc++.h> # define ll long long # define rg register # define il inline # define mem(a, num) memset(a, num, sizeof(a)) # define debug(s, x) cout << s << " -> " << x << endl const bool oj = true; using namespace std; template < typename T > il void readInt(T &x) { x = 0; rg T f = 1; rg char ch = getchar(); while(!isdigit(ch)) f = ch == '-' ? -1 : f, ch = getchar(); while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); x *= f; } template < typename T > il int Max(T a, T b) {return a > b ? a : b;} template < typename T > il int Min(T a, T b) {return a < b ? a : b;} void file() { freopen("1.in", "r", stdin); freopen("1.out", "w", stdout); } // ---head file--- // int date1, date2; //两个日期 int xhw[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //每个月有多少天,二月份由于闰年的原因,需要特殊处理一下。 il void change(int); //修改二月份的日期的函数 il bool orz(int, int, int); //判断日期是否是回文数的函数 int main() { if(!oj) file(); readInt(date1), readInt(date2); # define y1 Y1 //因为 y1 这个变量跟 cmath 库中某个东西有冲突,所以先在这里 define 一下 int y1 = date1 / 10000, y2 = date2 / 10000, m1 = date1 / 100 % 100, m2 = date2 / 100 % 100, d1 = date1 % 100, d2 = date2 % 100, ans = 0; //debug("y1", y1), debug("y2", y2), debug("m1", m1), debug("m2", m2), debug("d1", d1), debug("d2", d2); //以上是分解出两个日期的年、月、日 for(rg int x = y1; x <= y2; ++x) { //枚举年 int t1, t2; if(x == y1) t1 = m1; else t1 = 1; if(x == y2) t2 = m2; else t2 = 12; //在枚举月份的时候,需要注意一下。大家可以自己试着理解一下,如果有不理解的,可以私信我。这里因为版面等原因不再阐述。 for(int h = t1; h <= t2; ++h) { //枚举月 if(h == 2) change(x); //如果是二月份,进入 change 函数 for(int w = 1; w <= xhw[h]; ++w) //枚举日 if(orz(x, h, w)) ++ans; //如果年月日回文,ans 累加。 } } printf("%d", ans); //最后输出 ans 即可。 return 0; } il void change(int x) { xhw[2] = (((x % 4 == 0) && (x % 100 != 0)) || (x % 400 == 0)) ? 29 : 28; //如果该年为闰年,二月的天数改为 29,否则为 28。 } il bool orz(int x, int h, int w) { int a[10]; a[1] = x / 1000, a[2] = x / 100 % 10, a[3] = x / 10 % 10, a[4] = x % 10, a[5] = h / 10, a[6] = h % 10, a[7] = w / 10, a[8] = w % 10; //分解出 8 位年月日中的每一位 if(a[1] == a[8] && a[2] == a[7] && a[3] == a[6] && a[4] == a[5]) return true; //如果日期回文,返回 true return false; //否则,返回 false }
转载是允许的,但是除了博主同意的情况下,必须在文章的明显区域说明出处,否则将会追究其法律责任。