写在前面
在准备机考补天的过程中记录所得
第一轮在B站上刷到了N诺,所以第一轮全是通过N诺的机试攻略来复习的。(不是广告,基础差友好型)
http://noobdream.com/Major/majorinfo/4/
日期问题主要是对于年月日的处理,关键在于询问某年某月某日星期几,询问给定的两个日期之间相差多少天,询问某一月日是某一年的第几天。
天数统计
- 问题描述:给定两个日期,统计计算二者之间相差的天数。
- 问题解决:
①每年各个月份的天数不尽相同,需要维护一个月份天数的数组 f[13]
②返回的答案是一个计数器,从零开始累加,每完成一次循环内的操作就进行加一操作
③从较小的日期开始往后推进,日期加一,若超过该月对应天数,则天数归1,月份加一;月份超过12,则月份归一,年份加一 - 问题模板
int f[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};//这里按照非闰年列写
int d1,d2;//用整型输入两个日期
cin>>d1>>d2;
//从整型数字钟分解出年、月、日
//通常题目会规定输入天数为YYYYMMDD
int day = d%100;
d /= 100;
int month = d % 100;
d /= 100;
int year = d;
//如果题目没有定义传入的两个数据的大小关系的话,需要自己明确大小关系
//以下默认day/month/year数组中的第一个元素为较小值
int res = 0;//有的题目会定义相邻两天差距为两天,这个时候res初始值就要为1,具体情况具体分析
bool isrun(int d){
if(d%400 == 0 ||d%4 ==0&&d%100!=0)
return true;
else
return false;
}
while(day[0]!=day[1]||month[0]!=month[1]||year[0]!=year[1]){
if(isrun(year[0]))
f[2] = 29;
else
f[2] = 28;
day[0]++;
if(day[0]>f[month[0]]){
day[0] = 1;
month[0]++;
}
if(month[0]>12){
month[0] = 1;
year[0]++;
}
res++;
}
cout<<res<<endl;
确定某年某月某日星期几
- 问题描述:给定一个初始的年月日和其对应的星期几,之后求给出的另一个日期对应星期几
- 问题解决:
基本的求解可以基于天数统计,之后再对求得天数进行模七运算,可以通过维护一个星期几的数组,比如说给定的初始日期为星期一,则维护xingqi[7] = {1,2,3,4,5,6,7},则所需要求的日期应该对应的星期为xingqi[res%7] - 问题模板:略
某年的第N天的具体年月日
- 问题描述:给定年份和天数,需要输出该年第N天的年月日
- 问题求解:是天数统计的逆过程,同样需要维护一个月份-天数对应数组,维护一个累加器,年月日的累加变换与上相同。
- 问题模板
int f[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int sum;
int year;
cin>>sum>>year;
if(isrun(year))
f[2] = 29;//闰年判断的模板同上
int y = year,m = 1,d = 1;
while(sum--){
d++;
if(d>f[m]){
d = 1;
m++;
}
//通常给出的天数都会小于365,用不到年份的递增
}
cout<<y<<m<<d;//如果需要格式化输出,则需要根据题意要求注意对齐和位数
//比如printf("%4d-%2d-%2d",y,m,d);
小结与AC避雷
-
总结
①涉及到年月日的模拟推进的时候,先考虑日,再到月,再到年
②记住判断闰年的模板
③天数统计或者日期定位都需要维护一个累加器 -
AC避雷
①天数统计处循环体内每次都要判断闰年(或者每次年份发生了变化之后都要判断一下是否为闰年,且判断必要使用if-else型,不能只使用if型,不然非闰年的2月无法还原成28天)