【每天例题】蓝桥杯 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;
}

  

 

运行结果

 

posted @ 2023-04-09 13:37  山远尽成云  阅读(99)  评论(0)    收藏  举报