不是VIP会员,不能显示答案

题目解答

题目:
(回文日期)在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。
牛牛习惯用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日,用82位数字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

样例输入:
20000101
20101231
样例输出:
2
对于样例,符合条件的日期是20011002和20100102
算法提示:枚举年份,再根据年份得到回文的日期,最后判断每个日期是否构成回文,且在起始终止日期之间。
var st,st1:string;
    x,y,i,g,m,d,sum,j:longint;

function monthday(y,m:longint):longint;//得到第y年m月的天数。
begin
  if (m=1)or(m=3)or(m=5)or(m=7)or(m=8)or(m=10)or(m=12) then exit(31);
  if (m=4)or(m=6)or(m=9)or(m=11) then exit(30);
  if m=2 then
    if (y mod 400=0)or (y mod 4=0) and (y mod 100<>0)    then exit(29)
    else exit(28);
end;

function pd:boolean;
begin
  if (m<1)or(m>12) then exit(false);
  if (d<1)or(d> monthday(i,m) ) then exit(false);
  if i<1000 then exit(false);
  if (g mod 10000<x mod 10000) or(g mod 10000 >y mod 10000) then exit(false);
  exit(true);
end;

begin
  read(x,y);
  for i:=x div 10000 to y div 10000 do
  begin
    str(i,st1);//str函数作用将数字i转换成字符串,并赋值给st1;
    st:=‘00000000’;
    if length(st1)<>4 then continue;
    for j:=1 to 4 do
    begin
      st[j]:=st1[j];
      st[9-j]:=st1[j];
    end;
    val(st,g);  //val函数作用将字符串st转换成数字,并赋值给变量g;
    val(copy(st,5,2),m);
    val( copy(st,7,2) ,d);
    if pd then  inc(sum)      ;
  end;
  writeln(sum);
end.
考点: 0
分析:
解答: 此题的思路比较巧妙,没有考虑起始日期和终止日期,所以程序存在漏洞。
评论:
老师: 0