星期几的问题

已知公元1年1月1日是星期一,问某年某月某日是星期几?

Input
输入为三个正整数y,m,d,分别代表年、月、日。其中,1≤y≤500000000000, m和d保证合法。

Output
输出星期几,星期一到星期六分别用1到6表示,星期天用7表示。

首先需要明确的一点是,万年历以400年为一个周期!!也就是说在进行进一步的运算之前,可以先让year对400取模,从而大大简化计算。

下面先分析一下我的思路:不可能把每一年的总天数加起来再对7求模,这样运算量太大了。因为一个平年对7取模是1,一个闰年对七取模是2,所以可以一步步的缩小规模,将一个比400小的年数通过counter记录增加的余数,逐步减小到公元1年,然后再求出总天数,这样就好算很多了。

因为这个算法是我当时粗略的想的,感觉大致是对的,但是真正实现起来的时候出现了几个小问题,下面会具体分析一下。

#include<stdio.h>

int get_weekday(long long year,int month,int day);
int get_counter(long long year,int month,int day);
int get_days(int month,int day);
int is_leap(long long year);

int main() {
	long long year;
	int month,day;
	int result;
	
	scanf("%lld%d%d",&year,&month,&day);
	
	result=get_weekday(year,month,day);
	
	printf("%d\n",result);
	
	return 0;
}

int get_weekday(long long year,int month,int day) {
	int counter=0,days=0;
	int result;
	
	counter=get_counter(year,month,day);
	days=get_days(month,day);
	result=(counter+days)%7;
	
	if(!result) {
		return 7;
	}
	
	return result;
}

int get_counter(long long year,int month,int day) {
	int counter=0;
	
	year%=400;
	
	if(is_leap(year)) {
		if(month<=2) {
			counter--;
		}
	}

	
	if(!year) {
		counter--;
	}
	
	for(;year>1;year--) {
		if(is_leap(year)) {
			counter+=2;
		}
		
		else {
			counter++;
		}
	}
	
	return counter%7;
}

int is_leap(long long year) {
	int condition1,condition2;
	
	condition1=!(year%4)&&(year%100);
	condition2=!(year%400);
	
	if(condition1||condition2) {
		return 1;
	}
	
	return 0;
}

int get_days(int month,int day) {
	int monthdays[12]={0,31,28,31,30,31,30,31,31,30,31,30};
	int days=0;
	int i=0;
	
	for(i=0;i<month;i++) {
		days+=monthdays[i];
	}
	
	days+=day;
	
	return days%7;
}
  1. year的数据类型不能是int,设为long long就够了,否则会出现溢出;
  2. 第一次进行year对400的取模时,考虑会有的年份是400的倍数,取模后会变成公元0年,但实际我们后来计算天数的时候都是按照公元1年1月1日是星期一来进行计算的,我们又知道每往前推一年天数会少一天,所以counter需要自减一;
  3. 还有一种情况,比如要求1960 2 25是星期几,如果直接将1960%400=360判断为闰年,会让counter增加两天,但是实际上在2.29号之前的天数不会受该年是否为闰年的影响,只有在二月份之后的天数会受影响,因此在进入循环语句之前,先判断月份是否比二大,再继续操作;
  4. 最后一件小事情就是monthdays中的数组天数总是上一个月的天数,因此第一个元素是0,第十二个元素是第十一月的天数30。

以上均是个人所想,如果有不足或者更简单的做法请一定要在评论里指出哦!

猜你喜欢

转载自blog.csdn.net/qq_43256290/article/details/85106649