NOIP 普及组 2016 回文日期

传送门

https://www.cnblogs.com/violet-acmer/p/9859003.html

题解

思路1

  相关变量解释

    year1,month1,day1 : date1对应的年、月、日

    year2,month2,day2 : date2对应的年、月、日

  这道题算是考思维+Code能力??

  易得,每一年最多有一个回文日期;

  例如 2000 的回文日期为 2000 0002

  for i : year1 to year2

    找到每个 i 的回文日期对应的月(month)、日(day),并进行两个判断

    (1):判断month,day是否合法。

    (2):判断当前日期是否在date1与date2之间

思路2

  枚举月和日对应的回文年份,看其回文组成的八位数是否在date1和date2内,什么意思呢?

  例如,对于01月23日,其对应的回文年份为3210,其回文组成的八位数为 32100123,在和输入的date1与date2比较,看是否在其中,如果在,Count++;

  不用特判某一年是否为闰年,为什么呢?

  某年是否为闰年只会影响 2 月的天数,2月最多有 29 天,其对应的回文年份为 9220,但9220是闰年。

  思路2来自集训队队员博客:https://blog.csdn.net/QLU_minoz/article/details/83450635

AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define isSat(x) ((x) >= 1 &&(x) <= 12)//判断是否为合法的月份
 4 #define isRun(x) ((x%4 == 0 && x%100 != 0) || (x%400 == 0))//判断是否为闰年
 5 
 6 char data[2][8];
 7 int monthDay[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, //0 : 平年
 8                      {0,31,29,31,30,31,30,31,31,30,31,30,31}};//1 : 闰年
 9 
10 int Transform(int a,int b,int d){//将字符串对应的年、月、日转化成数子
11     int num=0;
12     for(int i=a;i <= b;++i)
13         num=num*10+(data[d][i]-'0');
14     return num;
15 }
16 void Search(int year,char *s){
17     int index=0;
18     do
19     {
20         s[index++]=year%10+'0';
21         year /= 10;
22     }while(year != 0);
23 }
24 void Solve()
25 {
26     int year1=Transform(0,3,0),month1=Transform(4,5,0),day1=Transform(6,7,0);
27     int year2=Transform(0,3,1),month2=Transform(4,5,1),day2=Transform(6,7,1);
28     int res=0;
29     int pre=0;
30     for(int i=year1;i <= year2;++i)
31     {
32         char s[4];
33         Search(i,s);//找到将当前的年份的回文
34         int month=(s[0]-'0')*10+(s[1]-'0');//当前年份的回文对应的月
35         int day=(s[2]-'0')*10+(s[3]-'0');//
36         if(!isSat(month) || day > monthDay[isRun(i)][month])
37             continue;
38         if(year1 == year2)
39         {
40             if(month > month1 || (month == month1 && day >= day1))
41             {
42                 if(month < month2 || (month == month2 && day <= day2))
43                     res++;
44             }
45         }
46         else
47         {
48             if(i == year1)
49                 res += (month > month1 || (month == month1 && day >= day1) ? 1:0);
50             else if(i == year2)
51                 res += (month < month2 || (month == month2 && day <= day2) ? 1:0);
52             else//如果year1 != year2 ,且 i != year1 && i != year2 ,则当前合法的日期一定在date1和date2之间
53                 res++;
54         }
55     }
56     printf("%d
",res);
57 }
58 int main()
59 {
60     scanf("%s%s",data[0],data[1]);
61     Solve();
62 }
思路1
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int date1,date2;
 4 int monthDay[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
 5 
 6 void Solve()
 7 {
 8     int res=0;
 9     for(int i=1;i <= 12;++i)//枚举月份
10         for(int j=1;j <= monthDay[i];++j)//枚举每月对应的日
11         {
12             int year=j%10*1000+j/10*100+i%10*10+i/10;//当前月,日对应的回文年份
13             int cnt=year*10000+i*100+j;//回文日期对应的八位数
14             res += (cnt >= date1 && cnt <= date2 ? 1:0);
15         }
16     printf("%d
",res);
17 }
18 int main()
19 {
20     scanf("%d%d",&date1,&date2);
21     Solve();
22 }
思路2
原文地址:https://www.cnblogs.com/violet-acmer/p/9860164.html