2 date questions

1.2 date issues

1, Date difference

1. Title and requirements

Time limit: 1s, memory limit: 32MB, special question: no

2. Summary

1) The judgment rule of leap year: if the number of the current year cannot be divided by 100 and can be divided by 4, it is a leap year, or it can be divided by
400 is also a leap year. In some cases, there may be two leap years eight years apart.

2) Macro definition function can be used to determine whether it is a leap year. The process of macro definition function is: the preprocessor replaces function call by copying macro code, which saves the process of function stack pressing and backstacking, and improves efficiency.
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0

3) Input technique: input eight consecutive digits to represent the date, use% 4d to read the first four digits, and use% 2d%2d to read the other last four digits. String processing is omitted.
scanf("%4d%2d%2d",&d.year,&d.month,&d.day);

4) Due to the need to calculate the difference between the input time and the specified origin time (specified as 0 / 0 / year), the calculation amount is large, so the data is considered to be preprocessed:

"Before the program actually starts processing the input data, preprocess and save the days difference between all the dates and the origin date. When the data is really input, it only needs to read out the saved data with 0 (1) time complexity, and the answer can be obtained with a little processing. "

Assuming that we calculate the days difference between all dates before December 31, 5001 and the origin date, we use buf[5001][13][32] 3D array to save the calculation results. In this way, you can directly use the subscript buf[year][month][day] to get the day difference between the month day of year and the origin date.

In "4", the following points need to be noted:

  1. Preprocessing is an important means of space for time (saving the memory needed for preprocessing data in exchange for the time consumption needed for real-time processing), which should be used as appropriate.
  2. buf[5001][13][32] is a memory consuming array, so it needs to be defined outside the function, that is, to define it as a global variable, or use functions such as malloc to dynamically apply for variable space in the function.
  3. One disadvantage of this method is that when the input date is one day in 5002, the correct result will not be obtained.

Due to the large amount of memory consumption, if the main function (other functions are the same) (the array is defined in), the stack space that its function can use will not be enough to provide such a large amount of memory, resulting in stack overflow and abnormal termination of the program. Therefore, the above methods must be referred to in case of such a large amount of memory space.

3. Thinking

In this paper, we investigate the most basic problem of date problems, which is to find the length of date intervals bounded by two specific dates. There is a unified idea to solve this kind of interval problem: to unify the original interval problem to the interval problem with a certain starting point.

In this example, the problem is unified to the difference of days between a specific date and an origin time. When the difference of days between two specific dates is required, as long as the difference of days between them and the origin date is subtracted, the difference of days between these two specific dates can be obtained (if necessary, add the absolute pair value).

4. Code
#include <iostream>
#include <string>
#include <cmath>
using namespace std;

struct Date{
	int year;
	int month;
	int day;
	
	Date(){
		year=0;month=0;day=0;
	}
}; 

int month(int i){
	switch(i){
		case 1:return 31;
		case 2:return 28;
		case 3:return 31;
		case 4:return 30;
		case 5:return 31;
		case 6:return 30;
		case 7:return 31;
		case 8:return 31;
		case 9:return 30;
		case 10:return 31;
		case 11:return 30;
		case 12:return 31;
	}
}

int calDays(Date *d){
	int days=0;
	int y_run = d->year/4,y_ping = d->year - y_run;
	//year 
	days = y_run*366+y_ping*365;
	//month 
	if(d->month>2){
		for(int i=1;i<=d->month;i++){
			days += month(i);
		}
		if((d->year % 4 ==0 && d->year % 100!=0) || d->year % 400 ==0){
			days += 1;
		}
	}
	//day
	days += d->day;
	return days; 
}

int main(){
	Date d1,d2;
	string s1,s2;
	int i=0;
//	cin>>s1>>s2;
	s1="20110412";
	s2="20110422";
	while(i<4) d1.year=d1.year*10+s1[i++];
	while(i<6) d1.month=d1.month*10+s1[i++];
	while(i<8) d1.day=d1.day*10+s1[i++];
	
	i=0;
	while(i<4) d2.year=d2.year*10+s2[i++];
	while(i<6) d2.month=d2.month*10+s2[i++];
	while(i<8) d2.day=d2.day*10+s2[i++];
	
	cout<<abs(calDays(&d1)-calDays(&d2))+1<<endl;
}
#include <stdio.h>
#include <iostream>
#include <cmath>
using namespace std;

#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
int buf[5001][13][32];

int dayOfMonth(int i,int isyeap){
	switch(i){
		case 1:return 31;
		case 2:
			if(isyeap){
				return 29;
			}
			return 28;
		case 3:return 31;
		case 4:return 30;
		case 5:return 31;
		case 6:return 30;
		case 7:return 31;
		case 8:return 31;
		case 9:return 30;
		case 10:return 31;
		case 11:return 30;
		case 12:return 31;
	}
}

struct Date{
	int year;
	int month;
	int day;
	
	Date(){
		year=0;month=0;day=0;
	}
	
	void nextDay(){
		day++;
		if(day>dayOfMonth(month,ISYEAP(year))){
			day=1;month++;
			if(month>12){
				month=1;year++;
			}
		}
	}
}; 


int main(){
	Date d1,d2;
	string s1,s2;
	int days=0;

	d1.day=1;d1.month=1;d1.year=0;
	while(d1.year!=5001){
		buf[d1.year][d1.month][d1.day]=days;
		d1.nextDay();
		days++;
	}
	//d1.year=2011;d1.month=4;d1.day=12;
	//d2.year=2011;d2.month=4;d2.day=22;
	scanf("%4d%2d%2d",&d1.year,&d1.month,&d1.day);
	scanf("%4d%2d%2d",&d2.year,&d2.month,&d2.day);
	printf("%d\n",abs(buf[d1.year][d1.month][d1.day]-buf[d2.year][d2.month][d2.day]))+1;
	return 0;
}

2, Day of Week

1. Title and requirements

Time limit: 1s, memory limit: 32MB, special question: no

2. Summary

(4 + ABS (caldays (& D1) - caldays (& D2))))% 7 can also be written as ((4 + caldays (& D1) - caldays (& D2))% 7 + 7)% 7

3. Thinking

According to the above example: know today's day of the week, know how many days are different from the input days. According to the 7-day cycle of the week, the input date is the day of the week.

4. Code
#include <cmath>
#include <string>
#include <iostream> 
using namespace std;

struct Date{
	int year;
	int month;
	int day;
	
	void setMonth(string s){
		if(s == "January") month = 1;
		else if(s == "February")month = 2;
		else if(s == "March")month = 3;
		else if(s == "April")month = 4;
		else if(s == "May")month = 5;
		else if(s == "June")month = 6;
		else if(s == "July")month = 7;
		else if(s == "August")month = 8;
		else if(s == "September")month = 9;
		else if(s == "October")month = 10;
		else if(s == "November")month = 11;
		else if(s == "December")month = 12;
		else month=0;
	}
};

int month(int i){
	switch(i){
		case 1:return 31;
		case 2:return 28;
		case 3:return 31;
		case 4:return 30;
		case 5:return 31;
		case 6:return 30;
		case 7:return 31;
		case 8:return 31;
		case 9:return 30;
		case 10:return 31;
		case 11:return 30;
		case 12:return 31;
	}
}

int calDays(Date *d){
	int days=0;
	int y_run = d->year/4,y_ping = d->year - y_run;
	//year 
	days = y_run*366+y_ping*365;
	//month 
	if(d->month>2){
		for(int i=1;i<=d->month;i++){
			days += month(i);
		}
		if((d->year % 4 ==0 && d->year % 100!=0) || d->year % 400 ==0){
			days += 1;
		}
	}
	//day
	days += d->day;
	return days; 
}

int main(){
	Date d1,d2;
	string m;
	d1.year=2020;d1.month=6;d1.day=4;
	
	cin>>d2.day>>m>>d2.year;
	d2.setMonth(m);

//2020.6.4 is Thursday
	switch((4+abs(calDays(&d1) - calDays(&d2)))%7){
		case 4: printf("Thursday\n");break;
		case 5: printf("Friday\n");break;
		case 6: printf("Saturday\n");break;
		case 0: printf("Sunday\n");break;
		case 1: printf("Monday\n");break;
		case 2: printf("Tuesday\n");break;
		case 3: printf("Wednesday\n");break;
	}
	return 0;
}

Posted by weezil on Thu, 04 Jun 2020 18:48:17 -0700