【每天例题】蓝桥杯 C语言 回文日期
回文日期
题目
https://www.lanqiao.cn/problems/498/learning/?page=1&first_category_id=1&sort=students_count
题目要求
1.该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
2.日期合法且为八位数。
思路分析
1.我们可以调用三个函数,第一个函数进行日期合法判断,第二个函数进行回文数判断,第三个函数进行特殊型判断
2.当三个函数结果都为1时满足要求
代码1
#include <stdio.h> #include <stdlib.h> int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 }; int c(int num) //日期是否合法 { int year = num/10000; int month = num%10000/100; int day = num%100; if(month==0||month>12) { return 0; } if(month!=2) { if(day==0||day>days[month]) { return 0; } } else { int l=year%400==0||(year%4==0&&year%100!=0); if(day==0||day>days[month]+l) { return 0; } } return 1; } int c1(int num) //检查回文 { if(num/10000000!=num%10) { return 0; } num%=10000000; if(num/1000000!=num%100/10) { return 0; } num%=1000000; if(num/100000!=num%1000/100) { return 0; } num%=100000; if(num/10000!=num%10000/1000) { return 0; } return 1; } int c2(int num) //检查ABABBABA回文 { int a1,a2,a3,a4,a5,a6,a7,a8; a1=num/10000000; a2=num%10000000/1000000; a3=num%1000000/100000; a4=num%100000/10000; a5=num%10000/1000; a6=num%1000/100; a7=num%100/10; a8=num%10; if(a1!=a3||a1!=a6||a1!=a8) { return 0; } if(a2!=a4||a2!=a5||a2!=a7) { return 0; } return 1; } int main(int argc, char *argv[]) { int n,a1,a2; scanf("%d",&n); for(int i=n+1; i<=99991231; i++) { if(c1(i)==1&&c(i)==1) { a1=i; break; } } for(int i=n+1; i<=99991231; i++) { if(c2(i)==1&&c(i)==1) { a2=i; break; } } printf("%d\n%d",a1,a2); return 0; }
代码2(由于没有合适的条件使得回文数日期与ABABBABA型日期区分开,故本条思路进行不下去,如果寻找到合适的条件,则可以直接使用switch-case即可)
该代码尝试将两个特殊型回文数代码缩短,但是如何让while停止在需要的位置是一个难点,当出现不符合日期判断或者符合回文数,该如何让他调到i++,并不进行满足的回文数代码呢?即当该数不符合日期判断,我应该使他跳到最后一步i++,当日期符合回文数n1,那下一个i++则不应该去进行n1的回文数判断,应该去到回文数n2进行判断。类似于满足case 0的语句输出后,后面的i++会直接去寻找满足case 1的语句,但是没有足够的条件去区分开case 0与case 1。
#include<stdio.h> int main() { int common[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };//平年 int leap[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };//闰年 int year,month,day; int n; int n1,n2; scanf ("%d",&n); int i=n; while(i>89991231) { year=i/10000; month=i%10000/100; day=i%100; if(month==0||month>12)//判断日期是否合法 { goto end; } if(month!=2) { if(day==0||day>common[month]) { goto end; } } else { if((year%400==0)||(year%4==0&&year%100!=0)); { if(day==0||day>leap[month]) { goto end; } } } int a1,a2,a3,a4,a5,a6,a7,a8;//分别对应第一位到第八位 a1=i/10000000; a2=i%10000000/1000000; a3=i%1000000/100000; a4=i%100000/10000; a5=i%10000/1000; a6=i%1000/100; a7=i%100/10; a8=i%10; /*问题出在以下部分,没有准确的条件区分开回文数if与ABABBABA型if,导致满足其中一个if输出后,后面的i++依旧会两个if一起判定*/ if((a1==a8)&&(a2==a7)&&(a3==a6)&&(a4==a5)) { n1=i; printf("%d",n1); goto end; } if(((a1==a3)&&(a1==a6)&&(a1==a8))&&((a2==a4)&&(a2==a5)&&(a2==a7))) { n2=i; printf("%d",n2); goto end; } end:i++; } return 0; }
运行结果