蓝桥杯——日期问题

博客围绕日期问题和高斯日记展开。日期问题涉及1960 - 2059年不统一格式日期,需判断对应可能日期,要进行字符串处理、合法性检验等;高斯日记用枚举法模拟翻日历,根据标注整数算出对应年月日。

日期问题:大小月,平闰年

2017-7-日期问题

若干混乱的历史文献,日期在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  

 1.常规日期运算大小月(30天/31天),平年/闰年,

 2.细心

 3.字符串处理

思路:逻辑上不复杂,但是要注意细节

1 把输入的字符串切割为三个整数(年月日)

2.日、月合法性检验(大小月,平闰年),不合法返回空字符串 

3.月,日如果少零,则补全 ( 首先把整数化为字符串 i2s(),用字符串的长度判断是否少0 ) 

4.用集合 set<string> 对三种 case( 年/月/日,日/月/年,月/日/年 )进行排序去掉重复

代码

#include<cstdio>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
bool isLeapYear(int year)
{
	if(year%4==0&&year%100!=0 || year%400==0)  return true;
	else return false;
}
void i2s(int i, string &s) //&s 传引用 
{
	stringstream ss;
	ss<<i;
	ss>>s;
}
string f(int a, int b, int c) //a年  b月  c日  
{
	//剔除不合法年月日,return "" 
	if(a>=60 && a<=99) a+=1900;
	if(a>=0 && a<=59)  a+=2000;
	if(b<1 || b>12) return "";
	if(c<1 || c>31)  return "";
	
	switch(b){
		case 2 : 
			if(isLeapYear(a) && c>29) return "";
			if(!isLeapYear(a) && c>28) return "";
		    break;
		case 4 :
			if(c>30) return "";
			break;
		case 6 :
			if(c>30) return "";
			break;
		case 9 :
			if(c>30) return "";
			break;
		case 11 :
			if(c>30) return "";
			break;
		default :
			break;
		
	}
	//月,日如果少零,则补全(首先把整数化为字符串,用字符串的长度判断是否少0) 
	string _a, _b, _c; 
	i2s(a, _a);
	i2s(b, _b);
	i2s(c, _c); 
	if(_b.length()==1) _b = "0" + _b;
	if(_c.length()==1) _c = "0" + _c;
	
	return _a+"-"+_b+"-"+_c;
	
	
}

int main(int argc, const char *argv[])
{
	// 输入的字符串切割为三个整数(年月日)
	string in;
	cin>>in;
	int a=0, b=0, c=0;
	a = (in[0]-'0')*10 + (in[1]-'0');
	b = (in[3]-'0')*10 + (in[4]-'0');
	c = (in[6]-'0')*10 + (in[7]-'0');
	string case1 = f(a, b, c);
	string case2 = f(c, a, b);
	string case3 = f(c, b, a);
	
	//对元素排序(日期从小到大),去重——set 
	set<string> ans;
	if(case1!="") ans.insert(case1);
	if(case2!="") ans.insert(case2);
	if(case3!="") ans.insert(case3);
	for(set<string>::iterator iter = ans.begin(); iter != ans.end(); iter++)
	{
		cout<<*iter<<endl;//* 指针 
	}
	
} 

 (1)字符串处理

1)  string in;
   cin>>in;
   int a = (in[0]-'0')*10 + (in[1]-'0');

2)  if(_b.length()==1) _b = "0" + _b;

3)
void i2s(int i, string &s) //&s 传引用 
{
	stringstream ss;   //#include<sstream>
	ss<<i;
	ss>>s;
}

(2) 集合set

set<string> ans;  //#include<set>
//在集合中插入元素
if(case1!="") ans.insert(case1);
if(case2!="") ans.insert(case2);
if(case3!="") ans.insert(case3);

//用迭代器遍历
for(set<string>::iterator iter = ans.begin(); iter != ans.end(); iter++)
{
	cout<<*iter<<endl;//* 指针 
}

 

2013-1-高斯日记

枚举法模拟翻日历 (这个题可以用excel做)

记日记不注明年月日,而是用一个整数代替,比如:4210   

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

高斯获得博士学位的那天日记上标着:8113           请你算出高斯获得博士学位的年月日。

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

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

bool isLeapYear(int year)
{
	return (( year%4==0 && year%100!=0 )|| year%400==0 ); 
}
int main(int argc, const char *argv[])
{
	int y = 1777;
	int m = 4;
	int d = 30;
	for(int i=1; i<8113 ;i++)
	{
		d++;
		if( d>31 && ( m==1 || m==3 || m==5 || m==7 || m==8 || m==10 ) )
		{
		    m++;
			d = 1;
		}
		if( d>30 && ( m==4 || m==6 || m==9 || m==11 ) )
		{
		    m++;
		    d = 1;
		}
		if( isLeapYear(y) && m==2 && d>29 )
		{
			m++;
			d = 1;
		}
		 if( !isLeapYear(y) && m==2 && d>28 )
		{
			m++;
			d = 1;
		}
		 if( d>31 && m==12 )
		{
			y++;
			m = 1;
			d = 1;
		}
		
		//cout<<y<<" "<<m<<" "<<d<<" "<<endl;
	}
	cout<<y<<" "<<m<<" "<<d<<" "<<endl;
}
//1799 7 16
### 蓝桥杯竞赛中的日期问题测试用例分析 在蓝桥杯竞赛中,日期问题是常见的考察点之一,通常涉及日期计算、闰年判断以及时间间隔等问题。这类题目不仅考验选手的基础算法能力,还要求具备较强的逻辑推理能力和代码实现技巧。 #### 1. 常见的日期问题类型 日期问题可以分为以下几类: - **闰年判断**:给定一个年份,判断其是否为闰年[^1]。 - **日期转换**:将某种格式的日期转化为另一种格式,或者计算两个日期之间的天数差[^2]。 - **星期推算**:已知某一天是星期几,求另一天对应的星期。 #### 2. 解决日期问题的核心思路 解决日期问题的关键在于掌握基本的时间单位换算规则和特殊条件处理方法。以下是几个重要的知识点: - 判断闰年的标准:如果年份能被4整除但不能被100整除,或者能被400整除,则该年为闰年。 - 计算两日期间相差天数时需要注意每个月的实际天数,尤其是二月可能有28天或29天。 #### 3. 示例代码展示 下面提供一段用于判断闰年的Python代码: ```python def is_leap_year(year): if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0): return True else: return False ``` 此函数可以根据输入的年份返回布尔值True或False来表明这一年是否为闰年。 对于更复杂的日期运算需求,可借助`datetime`模块完成精确操作: ```python from datetime import date, timedelta def days_between_dates(date1, date2): d1 = date.fromisoformat(date1) d2 = date.fromisoformat(date2) delta = abs(d2 - d1).days return delta ``` 上述代码片段展示了如何利用内置库快速获取任意两天之间的确切天数差异。 #### 4. 实际应用案例 假设有一道典型的蓝桥杯试题:“给出起始日与终止日,请问两者相隔多少整天?” 可以按照如下方式解答——先验证数据合法性;接着调用前述定义好的辅助功能完成最终统计工作并输出结果即可满足题目要求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值