【蓝桥杯练习】日期问题整理

类型一:给定某个日期问你是周几?
使用基姆拉尔森计算公式非常简单就能得到,且不易出错

void CaculateWeekDay(int y,int m, int d)
{
	if(m==1||m==2) {
		m+=12;
		y--;
	}
	//使用基姆拉尔森计算公式
	int iWeek=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
	switch(iWeek)
	{
	case 0: printf("星期一\n"); break;
	case 1: printf("星期二\n"); break;
	case 2: printf("星期三\n"); break;
	case 3: printf("星期四\n"); break;
	case 4: printf("星期五\n"); break;
	case 5: printf("星期六\n"); break;
	case 6: printf("星期日\n"); break;
	}
}

类型二:给你一个日期问你多少天都是几号?
如星系炸弹(2015年第六届蓝桥杯B组(C/C++)预赛 第二题)
“在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。

每个炸弹都可以设定多少天之后爆炸。

比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。

有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。”
就是一个for循环多少天就是多少次
然后每到一个月就月份++,每到一年就年份++,且月变成1,日也要变1
注意闰年平年的判断
核心代码如下:

 int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 for(int i=1;i<=1000;++i){
	  day++;
  if((year%100!=0&&year%4==0)||(year%400==0)){
		   month[2]=29;
	  }
	  else{
		month[2]=28;
	  }

	  if(day>month[mon]){
		mon++;
		cout<<mon<<endl;
		  if(mon>12){
			mon=1;
			year++;
		  }
		day=1;
	  }
  }

类型三:日期的比较以及日期结构体

如历届试题: 小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。 ​ 比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。 ​ 给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗
输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

输出

输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。

**样例输入

02/03/04

**样例输出

2002-03-04
2004-02-03
2004-03-02

#include <iostream>
#include<cstdio>
#include<set>
using namespace std;

int mon[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};
struct Date1{
int year;
int month;
int day;
//set的自定义排序,使用结构体内部重载<的方法
bool operator < (Date1 b) const
    {
        if (year == b.year)
        {
            if (month == b.month) {
                return day < b.day;
            }
            return month < b.month;
        }
        return year < b.year;
    }

}date[8];
int y,m,d;
bool isLeap(int yy){
	if((yy%4==0&&yy%100!=0)||(yy%400==0))return true;
	return false;
}

bool isVaild(Date1 date){
	if(date.year<1961||date.year>2059)return false;
	if(date.month<1||date.month>12)return false;
	if(isLeap(date.year)){//是闰年
		if(date.day>mon[1][date.month]||date.day<1){
			return false;
		}
	}
	else{
		if(date.day>mon[0][date.month]||date.day<1){
			return false;
		}
	}

      return true;
}

set<Date1> ss;
int main()
{
 scanf("%d/%d/%d",&y,&m,&d);
 //一共也就六种情况
 	date[0].year=y+2000;
	date[0].month=m;
	date[0].day=d;
	date[1].year=y+1900;
	date[1].month=m;
	date[1].day=d;
	date[2].year=2000+d;
	date[2].month=y;
	date[2].day=m;
	date[3].year=1900+d;
	date[3].month=y;
	date[3].day=m;
	date[4].day=y;
	date[4].month=m;
	date[4].year=d+2000;
   	date[5].day=y;
	date[5].month=m;
	date[5].year=d+1900;
  for(int i=0;i<6;i++){
	if(isVaild(date[i])){
		ss.insert(date[i]);
	}
  }

 for(set<Date1>::iterator it=ss.begin();it!=ss.end();it++){
	 printf("%d-%02d-%02d\n", (*it).year, (*it).month, (*it).day); // %02d: 不足二位则补0
 }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值