蓝桥杯——日期问题

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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值