编程之美2015资格赛 题目1 : 2月29日

时间限制:2000ms

单点时限:1000ms

内存限制:256MB

描述

给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期)。

只有闰年有2月29日,满足以下一个条件的年份为闰年:

1. 年份能被4整除但不能被100整除

2. 年份能被400整除

输入

第一行为一个整数T,表示数据组数。

之后每组数据包含两行。每一行格式为"month day, year",表示一个日期。month为{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"}中的一个字符串。day与year为两个数字。

数据保证给定的日期合法且第一个日期早于或等于第二个日期。

输出

对于每组数据输出一行,形如"Case #X: Y"。X为数据组数,从1开始,Y为答案。

数据范围

1 ≤ T ≤ 550

小数据:

2000 ≤ year ≤ 3000

大数据:

2000 ≤ year ≤ 2×109

样例输入
4
January 12, 2012
March 19, 2012
August 12, 2899
August 12, 2901
August 12, 2000
August 12, 2005
February 29, 2004
February 29, 2012
样例输出
Case #1: 1
Case #2: 0
Case #3: 1
Case #4: 3

以400为周期

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
  class Date{
    public Date(int day, int month, int year) {
      this.day = day;
      this.month = month;
      this.year = year;
    }
    int day,month,year;
  }

  String month[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"};
  Map<String,Integer> mapMonth = new HashMap<>();
  private void initMonth(){
    for(int i=0;i<month.length;i++){
      mapMonth.put(month[i], i+1);
    }
  }

  private int coutNum(String start,String end){
    Date st = date(start);
    Date ed = date(end);
    int res = 0;
    for(int i=((st.year-1)/4+1)*4;i<=ed.year/4*4;i+=4){
      if(i%400==0){
        res += (ed.year/400-i/400)*97;
        res++;
        i = ed.year/400*400;
      }else{
        if(isRun(i))res++;
      }
    }
    if(isRun(st.year)){
      if(st.month>2){
        res--;
      }
    }
    if(isRun(ed.year)){
      if(ed.month<2){
        res--;
      }else if(ed.month==2){
        if(ed.day < 29) res--;
      }
    }
    return res;
  }

  private boolean isRun(int year){
    if((year%4==0&&year%100!=0)||(year%400==0)) return true;
    return false;
  }

  private Date date(String str){
    String s[] = str.split(" ");
    int month = mapMonth.get(s[0]);
    int year = Integer.parseInt(s[2]);
    int day = Integer.parseInt(s[1].substring(0,s[1].indexOf(",")));
    return new Date(day, month, year);
  }

  public static void main(String args[]){
    Scanner sc = new Scanner(System.in);
/*    Scanner sc = null;
    try {
      sc = new Scanner(new FileInputStream("C:\\Users\\ddguo\\Desktop\\input.txt"));
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }*/
    int num = sc.nextInt();
    sc.nextLine();
    Main main = new Main();
    main.initMonth();
    int caseNum = 1;
    while(num-->0){
      String start = sc.nextLine();
      String end = sc.nextLine();
      String res = "Case #"+caseNum+": "+main.coutNum(start, end);
      System.out.println(res);
      caseNum++;
    }
    sc.close();
  }
}
时间: 2024-08-01 23:03:25

编程之美2015资格赛 题目1 : 2月29日的相关文章

编程之美2015资格赛

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之 后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Fe

编程之美2015资格赛A题

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之 后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Fe

hiho 编程之美2015资格赛(2月29日-模拟日期)

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Feb

微软2编程之美2015资格赛

题目1 :2月19日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Febr

编程之美2015 资格赛 hihocoder 题目2: 回文字符序列

思路:暴力搜,用BFS的方式,生成每一种可能,再对每一种可能进行判断是否回文,进行统计.严重超时!计算一个25个字符的,大概要20多秒! 1 #include <iostream> 2 #include <deque> 3 #include <string> 4 #include <stdio.h> 5 #include <cstring> 6 using namespace std; 7 8 deque<string> a; 9 1

编程之美2015 资格赛 hihocoder 题目3 : 基站选址

题意:给一个网格大小,在其中找一个基站,使得到每个用户之间的距离的平方(欧几里得距离的平方),和到其中任一个通讯的距离(曼哈顿距离)的总距离(代价)最小.其实就是到每个用户的距离最小的基础上,到通讯公司也要尽可能近,距离也就是代价. 思路:一开始觉得需要每个点都尝试,计算代价,再比较代价,找出基站最佳位置.但是,这样还叫算法?不是比穷举更快的算法都不叫算法!那么得想办法减少搜索的点,想到基站不可能建立在一个其某一个方向上完全没有用户或者通讯公司的地方,比如用户和通讯公司都在x坐标10以上,而我们

hiho 编程之美2015资格赛(基站选址-绝对值方程分段)[无数据]

题目3 : 基站选址 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方. 网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离). 在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价. 输入 第一行为一个整数T,表示数据组数. 每组数据第一行为四个整数:N, M,

编程之美2015资格赛:基站选址

题目3 : 基站选址 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方. 网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离). 在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价. 输入 第一行为一个整数T,表示数据组数. 每组数据第一行为四个整数:N, M,

编程之美2015资格赛:回文字符序列

题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据