题目链接:https://www.luogu.com.cn/problem/P8831
题目描述
在 1582 年之前,以 4 为倍数的年份为闰年。正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 天。如果这年是闰年,那么二月则有 29 天。
但某位教皇发现这么做其实不够准确,会造成误差,因此规定从 1582 年开始,以 4 为倍数的年份,除了以 100 为倍数且不为 400 的倍数年份,才是闰年。同时为了消除误差,规定 1582 年 10 月 4 日的下一天是 1582 年 10 月 15 日,中间的日期就当作不存在了。
现在给出日期,计算这个日期到公元 1 年 1 月 1 日经过的天数。
输入格式
按照
日月年
的格式输入数据,其中日是 1 到 31 之间的整数,月是三个大写字母,年是 1 到 9999 之间的整数。保证这个日期是合法且存在的。月份的大写字母:
- 1月:JAN
- 2月:FEB
- 3月:MAR
- 4月:APR
- 5月:MAY
- 6月:JUN
- 7月:JUL
- 8月:AUG
- 9月:SEP
- 10月:OCT
- 11月:NOV
- 12月:DEC
输出格式
输出一个整数表示答案
输入输出样例
输入 #1
1JAN1输出 #1
0输入 #2
4OCT1582输出 #2
577736输入 #3
15OCT1582输出 #3
577737输入 #4
21NOV2020输出 #4
737751
Java代码:
package _传智杯.练习赛;
import java.util.Calendar;
import java.util.Scanner;
public class 儒略历 {
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
String s=sc.next();
String year=null;
String month=null;
String day=null;
for(int i=0;i<s.length();i++){
if(!(s.charAt(i)>='0'&&s.charAt(i)<='9')){
day=s.substring(0,i);
month=s.substring(i,i+3);
year=s.substring(i+3);
break;
}
}
int month1=0;
int year1=Integer.parseInt(year);
int day1=Integer.parseInt(day);
if(month.equals("JAN")) month1=1;
if(month.equals("FEB")) month1=2;
if(month.equals("MAR")) month1=3;
if(month.equals("APR")) month1=4;
if(month.equals("MAY")) month1=5;
if(month.equals("JUN")) month1=6;
if(month.equals("JUL")) month1=7;
if(month.equals("AUG")) month1=8;
if(month.equals("SEP")) month1=9;
if(month.equals("OCT")) month1=10;
if(month.equals("NOV")) month1=11;
if(month.equals("DEC")) month1=12;
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c1.set(1,0,1);
c2.set(year1,month1-1,day1);
long x=c1.getTimeInMillis();
long y=c2.getTimeInMillis();
long res=(y-x)/1000/60/60/24;
System.out.println(res);
}
}
代码虽然AC,但我发现了一些问题:
Java中Calendar getTimeInMillis()方法返回值存在误差
当我将代码中c1,c2初始化时进行调换,即:
换成
发现输入相同时输出结果不同:
仅仅交换次序会造成结果不同?
原来是Java中Calendar getTimeInMillis()方法返回值存在误差,当c1.getTimeInMillis()-c2.getTimeInMillis()得到的两天之间相差的毫秒数并不能十分精确地表示实际相差的毫秒数。
以2020年11月21日为例:通过c1.getTimeInMillis()-c2.getTimeInMillis()可得知2020年11月21日到1年1月1日的毫秒数为63741686399998,而实际值应该为63741686400000,一天的毫秒数为86400000,当用63741686399998/86400000时得到737750天,63741686400000/86400000得到737751天
解决方案:
将最终结果进行四舍五入:
换成
最后可保证结果正确
最终代码:
package _传智杯.练习赛;
import java.util.Calendar;
import java.util.Scanner;
public class 儒略历 {
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
String s=sc.next();
String year=null;
String month=null;
String day=null;
for(int i=0;i<s.length();i++){
if(!(s.charAt(i)>='0'&&s.charAt(i)<='9')){
day=s.substring(0,i);
month=s.substring(i,i+3);
year=s.substring(i+3);
break;
}
}
int month1=0;
int year1=Integer.parseInt(year);
int day1=Integer.parseInt(day);
if(month.equals("JAN")) month1=1;
if(month.equals("FEB")) month1=2;
if(month.equals("MAR")) month1=3;
if(month.equals("APR")) month1=4;
if(month.equals("MAY")) month1=5;
if(month.equals("JUN")) month1=6;
if(month.equals("JUL")) month1=7;
if(month.equals("AUG")) month1=8;
if(month.equals("SEP")) month1=9;
if(month.equals("OCT")) month1=10;
if(month.equals("NOV")) month1=11;
if(month.equals("DEC")) month1=12;
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c1.set(1,0,1);
c2.set(year1,month1-1,day1);
long x=c1.getTimeInMillis();
long y=c2.getTimeInMillis();
long res= Math.round((y-x)/1000/60/60/24.0);
System.out.println(res);
}
}