6 条题解
-
2
正解: 枚举后面四位(月份+日期)会更快。
枚举后四位然后求出整个日期,判断是否在范围内。
2月不需要判断是否是闰年,因为0229反过来是9220,整个日期是92200229,而9220年是闰年。
#include<bits/stdc++.h> using namespace std; int x,y,cnt,month[51]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int main() { cin>>x>>y; for(int i=1;i<=12;i++) { for(int j=1;j<=month[i];j++) //i是月,j是日 { int c=(j%10)*1000+(j/10)*100+(i%10)*10+i/10; //将日月反转 int ans=c*10000+i*100+j; //将年放到前面 if(ans<x || ans>y)continue; //特判 cnt++; } } cout<<cnt; return 0; }
-
1
题解
思路1
老老实实,暴力枚举,写就得了。不过由于码量太大,这里不太推荐。
#include <bits/stdc++.h> using namespace std; int y_1, m1, d1, y_2, m2, d2, sum = 0; // y1和y2被占用了 int day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //存每个月的天数 bool check() { return (y_1 < y_2) || ((y_1 == y_2 && m1 < m2) || (y_1 == y_2 && m1 == m2 && d1 <= d2)); //首先,只要现在的年份小于结束年份就一定可以继续循环;然后,如果现在的年份和结束年份相等,且月份小于结束年份也可以循环;最后,只有天数不同,就必须现在的天数小于结束天数。 } int r(int x) { return ((x % 4 == 0 && x % 100 != 0) || (x % 400 == 0)) ? 29 : 28; //判断2月的天数 } bool palindrome(int y, int m, int d) { char s[8]; int t = y * 10000 + m * 100 + d; //将它重新组成日期 sprintf(s, "%d", t); //转换为字符 for (int i = 0; i < 4; i++) if (s[i] != s[8 - i - 1]) return false; return true; //判断回文 } int main() { int t1, t2; scanf("%d%d", &t1, &t2); y_1 = t1 / 10000; m1 = t1 / 100 % 100; d1 = t1 % 100; //分离出年份月份和日数 y_2 = t2 / 10000; m2 = t2 / 100 % 100; d2 = t2 % 100; while (check()) //判断是否枚举完 { bool f = 1; //f用于看是否一已经进行过日期更新 if (palindrome(y_1, m1, d1)) sum++; if ((m1 == 2 && d1 == r(y_1)) || (m1 != 2 && d1 == day[m1])) //一个月完了 { m1++; d1 = 1; f = 0; } if (m1 == 13) { y_1++; m1 = 1; d1 = 1; f = 0; } if (f) //如果月没有结束,就直接加天数即可 d1++; } printf("%d\n", sum); return 0; }
确实可以,但是你不觉得累吗?
思路2
我们既然枚举不行,我们就构造吧~
该如何构造呢?我们可以枚举年份,把年份翻转,此时一定为回文字符串,而且一年只会有一个回文日期,判断日期是否合法就可以了。
#include <bits/stdc++.h> using namespace std; string s1, s2; int ans; bool f(int x) { if ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) return 1; return 0; } int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int b[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 两个工具函数 int ttint(string s) { int ans = 0, m = 1; for (int i = s.length() - 1; i >= 0; i--) { ans += (s[i] - '0') * m; m *= 10; } return ans; } string ttstr(int n) { string ans = ""; while (n > 0) { ans = char(n % 10 + '0') + ans; n /= 10; } return ans; } int main() { cin >> s1 >> s2; // 必须cin // 这里也手动吧 int start = ttint(s1.substr(0, 4)); int end = ttint(s2.substr(0, 4)); for (int i = start; i <= end; i++) { string s3 = ttstr(i); // 我们这里用手动拆解法 string s4 = s3; reverse(s3.begin(), s3.end()); // 翻转 s4 = s4 + s3; //分离出日和月 int month = (s4[4] - '0') * 10 + (s4[5] - '0'); int day = (s4[6] - '0') * 10 + (s4[7] - '0'); if (s4 > s2 || s4 < s1) continue; if (f(i)) { if (month >= 1 && month <= 12) { if (day >= 0 && day <= b[month]) //if嵌套是看翻转的日期是否合法 ans++; } } else { if (month >= 1 && month <= 12) { if (day >= 0 && day <= a[month]) ans++; } } } printf("%d\n", ans); return 0; }
思路3
我们还可以枚举一年中的日期,计算日期的回文,判断年份是否在范围内。当然也有很多细节要注意,比如开始和结束年不完整。
#include <bits/stdc++.h> using namespace std; int x, y, cnt = 0; int f(int x) // 判断闰年 { if ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) return 1; else return 0; } int truedate(int x) // 判断日期 { int year = x / 10000, month = (x / 100) % 100, day = x % 100; if (month == 0 || month > 12) return 0; if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31) return 0; if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return 0; if (!f(year) && month == 2 && day > 28) return 0; if (f(year) && month == 2 && day > 29) return 0; return 1; } int main() { scanf("%d%d", &x, &y); int x1 = x / 10000, y1 = y / 10000; for (int i = x1; i <= y1; i++) { int n = i * 10000 + i % 10 * 1000 + i % 100 / 10 * 100 + i % 1000 / 100 * 10 + i / 1000; if (truedate(n) && n >= x && n <= y) cnt++; // 日期在范围内 } printf("%d\n", cnt); return 0; }
#include <bits/stdc++.h> using namespace std; int y_1, m1, d1, y_2, m2, d2, sum = 0; int day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; bool check() { return (y_1 < y_2) || ((y_1 == y_2 && m1 < m2) || (y_1 == y_2 && m1 == m2 && d1 <= d2)); } int r(int x) { return ((x % 4 == 0 && x % 100 != 0) || (x % 400 == 0)) ? 29 : 28; } bool palindrome(int y, int m, int d) { char s[8]; int t = y * 10000 + m * 100 + d; sprintf(s, "%d", t); for (int i = 0; i < 4; i++) if (s[i] != s[8 - i - 1]) return false; return true; } int main() { int t1, t2; scanf("%d%d", &t1, &t2); y_1 = t1 / 10000; m1 = t1 / 100 % 100; d1 = t1 % 100; y_2 = t2 / 10000; m2 = t2 / 100 % 100; d2 = t2 % 100; while (check()) { bool f = 1; if (palindrome(y_1, m1, d1)) sum++; if ((m1 == 2 && d1 == r(y_1)) || (m1 != 2 && d1 == day[m1])) { m1++; d1 = 1; f = 0; } if (m1 == 13) { y_1++; m1 = 1; d1 = 1; f = 0; } if (f) d1++; } printf("%d\n", sum); return 0; }
#include <bits/stdc++.h> using namespace std; string s1, s2; int ans; bool f(int x) { if ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) return 1; return 0; } int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int b[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int ttint(string s) { int ans = 0, m = 1; for (int i = s.length() - 1; i >= 0; i--) { ans += (s[i] - '0') * m; m *= 10; } return ans; } string ttstr(int n) { string ans = ""; while (n > 0) { ans = char(n % 10 + '0') + ans; n /= 10; } return ans; } int main() { cin >> s1 >> s2; // 必须cin // 这里也手动吧 int start = ttint(s1.substr(0, 4)); int end = ttint(s2.substr(0, 4)); for (int i = start; i <= end; i++) { string s3 = ttstr(i); string s4 = s3; reverse(s3.begin(), s3.end()); s4 = s4 + s3; int month = (s4[4] - '0') * 10 + (s4[5] - '0'); int day = (s4[6] - '0') * 10 + (s4[7] - '0'); if (s4 > s2 || s4 < s1) continue; if (f(i)) { if (month >= 1 && month <= 12) { if (day >= 0 && day <= b[month]) ans++; } } else { if (month >= 1 && month <= 12) { if (day >= 0 && day <= a[month]) ans++; } } } printf("%d\n", ans); return 0; }
#include <bits/stdc++.h> using namespace std; int x, y, cnt = 0; int f(int x) { if ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) return 1; else return 0; } int truedate(int x) { int year = x / 10000, month = (x / 100) % 100, day = x % 100; if (month == 0 || month > 12) return 0; if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31) return 0; if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return 0; if (!f(year) && month == 2 && day > 28) return 0; if (f(year) && month == 2 && day > 29) return 0; return 1; } int main() { scanf("%d%d", &x, &y); int x1 = x / 10000, y1 = y / 10000; for (int i = x1; i <= y1; i++) { int n = i * 10000 + i % 10 * 1000 + i % 100 / 10 * 100 + i % 1000 / 100 * 10 + i / 1000; if (truedate(n) && n >= x && n <= y) cnt++; } printf("%d\n", cnt); return 0; }
-
1
这题我是暴力的做法,首先对于输入的两个字符串,进行了字符串切割,利用了substr函数切割,该函数是从哪个下标开始往后连续几个字符,切割出来利用atoi转成了int类型,得到了两个年份起始和终止,然后我对这两个年份之间的所有年份,翻转后得到一个字符串,此时必然是回文,因此我直接判断这个日期是否合法
#include <bits/stdc++.h> #define ll long long using namespace std; string s1, s2; int ans; bool f(int x) { if (x % 4 == 0 && x % 100 != 0 || x % 400 == 0) return 1; return 0; } int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int b[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> s1 >> s2; int start = atoi(s1.substr(0, 4).c_str()); int end = atoi(s2.substr(0, 4).c_str()); for (int i = start; i <= end; i++) { string stream ss; ss << i; string s3 = ss.str(); //上面三行是int直接流转成了字符串。可以自己利用数位拆分的方法实现。 string s4 = s3; reverse(s3.begin(), s3.end()); s4 = s4 + s3; int month = (s4[4] - '0') * 10 + (s4[5] - '0'); //分离出日和月 int day = (s4[6] - '0') * 10 + (s4[7] - '0'); if (s4 > s2 || s4 < s1) continue; if (f(i)) { if (month >= 1 && month <= 12) { if (day >= 0 && day <= b[month]) //if嵌套是看翻转的日期是否合法 ans++; } } else { if (month >= 1 && month <= 12) { if (day >= 0 && day <= a[month]) ans++; } } } cout << ans; return 0 }
-
0
不多说,太简单了(暴力枚举)
#include<iostream> //基本不需要什么,只需要iostream或者cstdio.就行 using namespace std; int date1,date2,y,m,d,cnt;//cnt记录符合条件的日期数,y是年,m是月,d是日 bool run_nian (int year){//我懒,我就写了一个判断是否闰年 if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } int save(){//获取年月日 return y*10000+m*100+d; } int main(){ cin>>date1>>date2; y=date1/10000; m=date1/100%100; d=date1%100; while(save()<=date2){//枚举 int l=10000000,r=1; bool f=1;//提前设置一个f for(int i=1;i<=4;i++){ if(save()/l%10!=save()/r%10){ f=0;//如果不是回文数那就让f=0,然后退出循环 break; }l/=10; r*=10; } if(f)//只要f不是0,cnt就加一 cnt++; if((m==1 || m==3 || m==5 || m==7 || m==8 || m==10 )&&d==31){//别问我12在哪,12月在第42行,它最特殊 m++;//31天的 d=1; }else if((m==4 || m==6 || m==9 || m==11)&&d==30){ m++;//30天的 d=1; }else if(m==2&&d==29&&run_nian(y)){//2月的特殊处理 m++;//闰年 d=1; }else if(m==2&&d==28&& !(run_nian(y))){ m++;//平年 d=1; }else if(m==12&&d==31){//针对12月的特殊处理 y++; m=1; d=1; }else//都没就让d加一 d++; }cout<<cnt;//输出cnt return 0; }
-
0
#include <iostream> #include <sstream> using namespace std; int l, r, ans; bool huiwen(int x){ stringstream ss; ss << x; for (int i = 0; i < 8; i++) if (ss.str()[i] != ss.str()[8 - i - 1]) return false; return true; } int main(){ cin >> l >> r; for (int i = l / 10000; i <= r / 10000; i++){ int m = i % 10 * 10 + i / 10 % 10, d = i / 100 % 10 * 10 + i / 1000; if ((m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) && d <= 31 && huiwen(i * 10000 + m * 100 + d)) ans++; if ((m == 4 || m == 6 || m == 9 || m == 11) && d <= 30 && huiwen(i * 10000 + m * 100 + d)) ans++; if (m == 2) if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) if (d <= 29 && huiwen(i * 10000 + m * 100 + d)) ans++; else if (d <= 28 && huiwen(i * 10000 + m * 100 + d)) ans++; } cout << ans; }
-
0
先列举年份,再列举月份,然后列举日期,这样做可以减少时间复杂度(就是有些判断有点长……)。
#include<bits/stdc++.h> using namespace std; int date1, date2, ans; bool hw(int n) { return (n / 10000000 == n % 10 && n / 1000000 % 10 == n / 10 % 10 && n / 100000 % 10 == n / 100 % 10 && n / 10000 % 10 == n / 1000 % 10); } bool rn(int n) { return ((n % 4 == 0 && n % 100 != 0) || n % 400 == 0); } int main() { cin >> date1 >> date2; for (int i = date1 / 10000; i <= date2 / 10000; i++) { for (int j = 1; j <= 12; j++) { int x; if (j == 1 || j == 3 || j == 5 || j == 7 || j == 8 || j == 10 || j == 12) x = 31; else if (j > 2) x = 30; else { if (rn(i)) x = 29; else x = 28; } for (int k = 1; k <= x; k++) if (hw(i * 10000 + j * 100 + k)) ans++; } } cout << ans; return 0; }
- 1
信息
- ID
- 1393
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 225
- 已通过
- 89
- 上传者