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代码
思路11 #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\n",res); 57 } 58 int main() 59 { 60 scanf("%s%s",data[0],data[1]); 61 Solve(); 62 }思路21 #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\n",res); 17 } 18 int main() 19 { 20 scanf("%d%d",&date1,&date2); 21 Solve(); 22 }