题目描述
牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月 份,最后2位代表日期。显然:一个日期只有一种表示方法,而两个不同的日期的表 示方法不会相同。
牛牛认为,一个日期是回文的,当且仅当表示这个日期的8位数字是回文的。现 在,牛牛想知道:在他指定的两个日期之间包含这两个日期本身),有多少个真实存 在的日期是回文的。
一个8位数字是回文的,当且仅当对于所有的i ( 1 <=i<= 8 )从左向右数的第i个 数字和第9-i个数字(即从右向左数的第i个数字)是相同的。
例如:
•对于2016年11月19日,用8位数字20161119表示,它不是回文的。
•对于2010年1月2日,用8位数字20100102表示,它是回文的。
•对于2010年10月2日,用8位数字20101002表示,它不是回文的。
每一年中都有12个月份:
其中,1、3、5、7、8、10、12月每个月有31天;4、6、9、11月每个月有30天;而对于2月,闰年时有29天,平年时有28天。
一个年份是闰年当且仅当它满足下列两种情况其中的一种:
1.这个年份是4的整数倍,但不是100的整数倍;
2.这个年份是400的整数倍。
例如:
•以下几个年份都是闰年:2000、2012、2016。
•以下几个年份是平年:1900、2011、2014。
输入输出格式
输入格式:
输入包括两行,每行包括一个8位数字。
第一行表示牛牛指定的起始日期。
第二行表示牛牛指定的终止日期。
保证date_i和都是真实存在的日期,且年份部分一定为4位数字,且首位数字不为0。
保证date1 —定不晚于date2。
输出格式:
输出一行,包含一个整数,表示在date1和date2之间,有多少个日期是回文的。
输入输出样例
输入样例#1:
20110101
20111231
输出样例#1:
1
输入样例#2:
20000101
20101231
输出样例#2:
2
说明
【样例说明】
对于样例1,符合条件的日期是20111102。
对于样例2,符合条件的日期是20011002和20100102。
【子任务】
对于60%的数据,满足date1 = date2。
这题我是用暴力直接搜,所以只对了六个点,拿了60分,还有四个点超时。
此题我的思路是直接一个 for 过去,再判断是否符合回文素数的要求。
代码如下:
var x,y,j,i,o,ans:longint;
s:string;
function pd:boolean;
var year,day,month:longint;
x:string;
begin
pd:=true;
x:=copy(s,1,4);val(x,year);
x:=copy(s,5,2);val(x,month);
x:=copy(s,7,2);val(x,day);
case month of
1,3,5,7,8,10,12:if (day>31)or(day<0) then begin pd:=false; exit; end;
4,6,9,11:if (day>30)or(day<0) then begin pd:=false; exit; end;
2:if (year mod 400=0)or(year mod 4=0)and(year mod 100<>0) then if day>29 then begin pd:=false; exit; end
else if day>28 then begin pd:=false; exit; end;
end;
end;
begin
assign(input,'date.in');
assign(output,'date.out');
reset(input);
rewrite(output);
read(x);
read(y);
for i:=x to y do
begin
str(i,s);
if (copy(s,5,2)>'12')or(copy(s,5,1)='0')and(copy(s,6,1)='0')or(copy(s,7,2)>'31')or(copy(s,7,1)='0')and(copy(s,8,1)='0')or(copy(s,1,1)='0') then continue;
o:=0;
for j:=1 to length(s)div 2 do if s[j]<>s[length(s)-j+1] then begin o:=1; break; end;
if o=0 then if pd=true then inc(ans);
end;
write(ans);
close(input);
close(output);
end.
修改后的算法:
枚举年分,年份中再枚举月份,再枚举日期,就可以避免没必要的循环。
代码如下:
const
a:array[1..12]of longint=(31,28,31,30,31,30,31,31,30,31,30,31);
var
s1,s2,s,m,d,i,j,k,ys,ye,ms,me,ds,de:longint;
begin
readln(s1);
readln(s2);
ys:=s1 div 10000;
ye:=s2 div 10000;
ms:=(s1 mod 10000)div 100;
me:=(s2 mod 10000)div 100;
ds:=s1 mod 100;
de:=s2 mod 100;
for i:=ys to ye do
begin
a[2]:=28;
if (i mod 4=0)and(i mod 100<>0)or(i mod 100=0)and(i mod 400=0) then
a[2]:=29;
for j:=1 to 12 do
if (i=ys)and(j>=ms)or(i=ye)and(j<=me)or(1=1) then
begin
if j<10 then m:=j*10
else m:=(j mod 10*10)+(j div 10);
for k:=1 to a[j] do
if (i=ys)and(j=ms)and(k>=ds)or(i=ye)and(j=me)and(k<=de)or(1=1) then
begin
if k<10 then d:=k*10
else d:=(k mod 10*10)+(k div 10);
if i=d*100+m then begin inc(s);break; end;
end;
if i=d*100+m then break;
end;
end;
writeln(s);
close(input);
close(output);
end.