zoukankan      html  css  js  c++  java
  • NOIP2016普及组第二题——回文日期

    题目描述

    牛牛习惯用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.
  • 相关阅读:
    javascript:浮动div,可拖拽div,遮罩层(div和iframe实现)
    c#委托初探
    工业化生产:简单工厂、工厂方法和抽象工厂模式
    javascript:面向对象编程基础:多态
    sql server:自定义函数初探
    ajax:数据传输方式简介
    javascript:对cookie的基本操作
    javascript:内置对象学习笔记一
    保证一个类仅有一个实例:单例模式
    ajax:简单搜索实践篇
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412479.html
Copyright © 2011-2022 走看看