This is a problem cited from the qualification round of Beauty of Programming 2015, which demands counting the number of Feb 29 between the two given dates (both inclusively):
My solution is as follow (it may seem a little clumsy):
1 import java.util.*; 2 3 public class Main { 4 public static Scanner in; 5 6 public static boolean isLeap(int year) { 7 return ( year%400==0)||(year%100>0&&year%4==0); 8 } 9 public static boolean sameYearBefore(String month,int day,int year) { 10 // Whether there‘s a Feb 29 before the given date in the same year 11 if (!isLeap(year)) { 12 return false; 13 } else if (month.equals("February") && day==29) { 14 return false; 15 } else { 16 return !month.equals("January")&&!month.equals("February"); 17 } 18 } 19 public static int sameCycleBefore(String month,int day,int year) { 20 // The number of leap years in the same 400-year cycle 21 // before the given date (0<=year<400) 22 int val = (year+3)/4; 23 if (year>0) { 24 val -= (year-1)/100; 25 } 26 if (sameYearBefore(month,day,year)) { 27 return val+1; 28 } else { 29 return val; 30 } 31 } 32 public static void main(String[] args) { 33 in = new Scanner(System.in); 34 int time = in.nextInt(); 35 for (int t = 0;t<time;t++) { 36 int val = 0; 37 String month = in.next(); 38 String tmp = in.next(); 39 int day = Integer.parseInt(tmp.substring(0,tmp.length()-1)); 40 int year1 = in.nextInt(); 41 val -= sameCycleBefore(month,day,year1%400); 42 month = in.next(); 43 tmp = in.next(); 44 day = Integer.parseInt(tmp.substring(0,tmp.length()-1)); 45 int year2 = in.nextInt(); 46 val += sameCycleBefore(month,day,year2%400); 47 val += 97*(year2/400-year1/400); 48 if (isLeap(year2)&&month.equals("February") && day==29) { 49 val++; 50 } 51 System.out.println("Case #"+(t+1)+": "+val); 52 } 53 in.close(); 54 } 55 }
========================= 旧地如重游月圆更寂寞 =========================
Actually, this problem may be not worth mentioning, but what I want to talk about is an application of integer division in programming.
To distribute n elements into m groups as evenly as possible, group j should contain (n+m-1-j)/m elements (if we want the group with a smaller index would have relatively more elements). In this way, the group with the largest element number would contain (n+m-1)/m elements (the ceiling of n over m) and the group with the smallest element number would have n/m elements (the floor of n over m), which indicates that the element number difference between two groups won‘t be greater than 1. Of course, such solution is also based on the fact that the summation of all those (n+m-1-j)/m is equal to n, which I learned last summer from Donald Knuth‘s book Concrete Mathematics:
If we interleave the elements from an array into groups, there will be a mapping from the original position of an element into its current position: group[j][i] is initially at array[i*m+j] and array[pos] is currently at group[pos%m][pos/m].
有点脑残,仅供娱乐。