在杭电上刷题也有4个多月了,做了有100+题目,每次做完一题都会回想一下做题的过程,顺便产生一点启发。
今天下午做了一道HDU 4515的模拟题,觉得有必要对自己从思考开始到最后AC掉的这个过程进行总结,大神们可以略过,这篇文章只是自己的一个笔记吧。
一、先看一下题目,分析。
2 6 30
2013/03/30 2013/03/18 2013/04/23 2013/02/22
此题意思比较浅显,很容易明白的。给定一个日期,然后向前向后加多少天,最后输出结果。
首先我们要确立整体的框架。
二、是否有能力做
此题没有用到任何数据结构和算法的知识,应该是很容易做出来的。
三、确定整体框架
即输入:样例个数 以及 一个整数 day
输出:
printf("%04d/%02d/%02d %04d/%02d/%02d\n",p_y,p_m,p_d,b_y,b_m,b_d);
所以我们可以先把整体框架敲出来
#include <iostream> #include <cstring> using namespace std; int main(){ int day,N; cin>>N; while(N--){ cin>>day; printf("%04d/%02d/%02d %04d/%02d/%02d\n",p_y,p_m,p_d,b_y,b_m,b_d); } }
四、框架出来后,就可以思考过程
这题应该分为两个部分
第一个部分是往后加时间
第二个部分是往前减时间
我们先来想第一部分:
如果输入的day很大的话,比如说1000天。那我们应该考虑要用循环,循环内部应该是每经历一次循环应该减多少天,知道最后1000天的day满足小于某一个月的天数
因此我们可以写个循环,跳出条件也可以确定了。然后可以用数组来写入12个月,因为年份又有闰年和平年之分,所以我们用二位数组来写入闰年和平年的月
int main(){ int day,N; int year[12][2]={{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}}; int p_y,p_m,p_d; int b_y,b_m,b_d; p_y = b_y = 2013; p_m = b_m = 3; p_d = b_d = 24; cin>>N; while(N--){ cin>>day; //向后加 while(天数x 大于 某一个月的天数){ } //向前减 while(天数x 大于 某一个月的天数){ } printf("%04d/%02d/%02d %04d/%02d/%02d\n",p_y,p_m,p_d,b_y,b_m,b_d); } }
两个主题部分框架已经写好了,再往里面思考
day比较大的时候,year也是要改变的,
那么year的改变有两种情况 1:到12月份的时候,还要往后加 2:到1月份的时候还要往后减
所以我们先写出判断闰年的函数
int is_year(int year){ if((year%4==0&&year%100!=0)||(year%400==0)){ return 1; }else{ return 0; } }
if(i == 11){ (p_y)++; is_ry = is_year(p_y); p_m = 1; }else{ p_m++; }
相应的在下面的向后减额循环中也写入相应的判断
if(i == 0){ (b_y)--; is_ryy = is_year(b_y); b_m = 12; }else{ b_m--; }
int main() { int N,M,day; int i,j; int is_ry,is_ryy; int year[12][2]={{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}}; int p_y,p_m,p_d; int b_y,b_m,b_d; cin>>N; while(N--){ cin>>day; p_y = b_y = 2013; p_m = b_m = 3; p_d = b_d = 24; //************************************ i = p_m - 1; int x = day + p_d; while(x > year[i][is_ry]){ if(i == 11){ (p_y)++; is_ry = is_year(p_y); p_m = 1; }else{ p_m++; } } //************************************ i = b_m - 1; x = b_d - day; while(x < 1){ if(i == 0){ (b_y)--; is_ryy = is_year(b_y); b_m = 12; }else{ b_m--; } } //************************************* printf("%04d/%02d/%02d %04d/%02d/%02d\n",p_y,p_m,p_d,b_y,b_m,b_d); } return 0; }
到这一步基本要接近尾声了,要考虑大概循环跳出的时候要执行那些语句了。以及循环开始前需要哪些初始化的语句,我就不细说了。
做的很粗糙,算是一个笔记吧。贴出整个代码
#include <iostream> #include <cstring> using namespace std; int is_year(int year){ if((year%4==0&&year%100!=0)||(year%400==0)){ return 1; }else{ return 0; } } int main() { int N,M,day; int i,j; int is_ry,is_ryy; int year[12][2]={{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}}; int p_y,p_m,p_d; int b_y,b_m,b_d; cin>>N; while(N--){ cin>>day; p_y = b_y = 2013; p_m = b_m = 3; p_d = b_d = 24; //************************************ i = p_m - 1; int x = day + p_d; is_ryy = is_ry = is_year(p_y); while(x > year[i][is_ry]){ if(i == 11){ (p_y)++; is_ry = is_year(p_y); p_m = 1; }else{ p_m++; } x -= year[i][is_ry]; i = p_m - 1; i %= 12; } p_d = x; //************************************ i = b_m - 1; x = b_d - day; while(x < 1){ if(i == 0){ (b_y)--; is_ryy = is_year(b_y); b_m = 12; }else{ b_m--; } i = b_m - 1; x += year[i][is_ryy]; } b_d = x; //************************************* printf("%04d/%02d/%02d %04d/%02d/%02d\n",p_y,p_m,p_d,b_y,b_m,b_d); } return 0; }