赞
踩
日期问题:大小月,平闰年
若干混乱的历史文献,日期在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;//* 指针
- }
枚举法模拟翻日历 (这个题可以用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

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。