高斯的日记(日期类计算题)

本文介绍了解析数学家高斯特殊日记记录方式的方法,通过两种不同的算法实现将高斯日记中的整数转换为具体日期,一种是手动计算年月日,另一种是利用Java的Calendar类进行日期计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[问题描述]

大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210。后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。
这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

高斯出生于:1777年4月30日。

在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

高斯获得博士学位的那天日记上标着:8113

请你算出高斯获得博士学位的年月日。

提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21

[我的答案]

public class MyAnswer {
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner sc=new Scanner(System.in);
		int sum_day=sc.nextInt();
		int initial=365-31-28-31-30+1;
		int[] month_day=new int[] {31,28,31,30,31,30,31,31,30,31,30,31};
		int year;
		int month=4;//
		int day=30;
		sum_day=sum_day-initial;
		year=sum_day/365;
		
		//判断闰年
		int run_year=0;
		for(int i=0;i<year;i++) {
			if(((i+1778)%4==0 &&(i+1778)%400!=0) || (i+1778)%400==0) {
				run_year++;
			}
		}
		sum_day=sum_day%365-run_year;
		year=year+1778;
		int a=0;
		if((year%4==0 &&year%400!=0) || year%400==0) {
			a=1;
		}else {
			a=0;
		}
		for(int i=0;i<12;i++) {
			if(i==3) {
					sum_day=sum_day-a;
				}
			if(sum_day>month_day[i]) {
				sum_day=sum_day-month_day[i];
			}else {
				month=i;
				day=sum_day;
			}
		}
		month=month+1;
		
		System.out.println(year+"-"+month+"-"+day);
		
		
	}

}

在上面的代码中,有几个错误没有注意:

1.日的初值应该从1开始。而不是0。

2.我的输入最小值为246,也就是1778年1月1日开始,否则是负值。

3.在我输入246的时候,出现了1778年12月0日,所以在月份和日的计算上,都少了1。

[正确答案1]

 

import java.util.Scanner;

public class Answer1 {

  public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    int x = sc.nextInt();
    int y = 1777;
    int m = 4;
    int d = 30;

    for (int i = 2; i <= x; i++) {
      d++;
      if (m == 2 && ((isLeap(y) && d == 30)||(!isLeap(y) && d == 29))) {
    	  //闰年的2月的30日等于3月1日,非闰年的2月29日相当于3月1日
        m=3;
        d=1;
      } else if (m==12&&d==32) { //12月32日相当于下一年的1月1日
        y++;
        m=1;
        d=1;
      }else if (d == 32 && (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10) ) 
      {
        //大月的32日等于次月的1日s
        m++;
        d = 1;
      } else if (d == 31 && (m == 4 || m == 6 || m == 9 || m == 11)) 
       {
         //小月的31日等于次月的1日
         m++;
         d = 1;      
        }
    }
    System.out.println(y+"-"+m+"-"+d);
    
    System.out.println((2006 & 3));
  }
  /**
   * 判断年份是否闰年
   * @param year
   * @return
   */
  public static boolean isLeap(long year) {
    return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
  }
}

上面的代码逻辑是:从1777年4月30日开始加,这里有一个注意点,4月30号这一天是1,所以循环中从2开始。接着判断一些进位条件,首先是d如果等于30或31,对应上月份,然后重置月份和日。若是闰年,2月单独一个if判断语句。当月份到12且日为32,年份加一。

在这里需要提一下,判断闰年的算法中,第一个语句 (year & 3) == 0 等价于 year%4==0 ,因为按位与运算中,从第3位到最高位都是4的倍数,所以只要倒数第一、二位为00的时候,才能为0,也就不是4的倍数。

[正确答案2]

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class Answer2 {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int d=sc.nextInt();
		Calendar day=new GregorianCalendar();
		day.set(1777, 3, 30);
		day.add(Calendar.DATE, d-1);
		System.out.println(day.get(Calendar.YEAR )+"-"+(day.get(Calendar.MONTH)+1)+"-"+day.get(Calendar.DATE));
		
	}

}

这是用了Java中的Calendar类(日历类),主要是其中的set、add、get三个函数。在本题中,需要考虑和验证的是,日历类中的月份是从0-11,最后输出的时候需要加1,同时在计算天数的时候,要从第二天开始算,因为4月30日是第一天。

其实,本题最保险的检验方法是,从题目中给的5343,1791年12月15日开始算,和8113差值放入add函数中,这样就能避免4月30日是第一天的难点。

[总结]

本次的题目,需要学习和注意的有以下几点:

1.闰年的判断条件(位运算符的运算技巧)。

2.计算思路,是从年-月-日计算顺序,还是日-月-年的计算顺序。

3.日历类Calendar的用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值