20130323编程马拉松被虐第一题

  如题,参加腾讯的编程马拉松比赛,由于好久没有码C++代码,错误百出,2个小时竟没有完成第一题!(一共有5道)

  痛定思痛,开博搞起。

  坚持学习C++,每天进步一点点!

  第一题题目是(经简化,出题人太爱扯淡,就不耽误大家时间了):

 

 

小Q和HR相约在腾讯第二届编程马拉松大赛进行到第5天的时候(即2013年3月24日),一起“向前穿越D天,然后开启幸福新生活”。

 

其勇气可谓令人赞叹,但可怜的小Q却总是备受折磨——小Q理解的”向前穿越”是朝着未来的方向,而女友HR理解的“向前穿越”却是朝着古代的方向!

 

假设已知现在的日期和穿越的天数D,你能计算出小Q和女友各自到达的年代吗?

 

 

 

Input

 

 

 

  输入首先包含一个整数N,表示有N组测试用例;

 

  接下来N行是N组数据,每一行包含一个正整数D(D<=10,0000),D表示向前穿越的天数。

 

 

 

Output

 

 

 

  请计算并输出小Q和女友分别到达的日期,日期格式为YYYY/MM/DD,两个日期中间用一个空格隔开,每组数据占一行,具体输出格式请参见样例。

 

 

 

Sample Input

 

 

 

2

 

6

 

30

 

 

 

Sample Output

 

 

 

2013/03/30 2013/03/18

 

2013/04/23 2013/02/22

 

 

  我的解法是:

View Code
  1 #include <iostream>
  2  #include <iomanip>
  3  using namespace std;
  4  bool IsLeapYear(int x)
  5  {
  6      if( x/100*100 == x )
  7      {
  8          if( x/400*400 == x )
  9          {
 10              return true;
 11          }
 12          else
 13          {
 14              return false;
 15          }
 16      }
 17      else
 18      {
 19          if( x/4*4 == x )
 20          {
 21              return true;
 22          }
 23          else
 24          {
 25              return false;
 26          }
 27      }
 28  }
 29  
 30  int main()
 31  {
 32      int D[100]={};
 33      int N=0;
 34      int year=2013,
 35          month=3,
 36          day=24,
 37          y=2013,
 38          m=3,
 39          d=24,
 40          delta=0,
 41          days=0;
 42      int monthDay[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 43      
 44      cin>>N;
 45  
 46      for(int i=1;i<N+1;i++)
 47      {
 48          cin>>D[i];
 49      }
 50  
 51      for(int i=1;i<N+1;i++)
 52      {
 53              
 54          //xiao q
 55          delta=D[i];
 56          y=year;
 57          m=month;
 58          d=day;
 59          y=year+delta/365;
 60          delta=delta-delta/365*365;
 61          if( delta==0 )
 62          {
 63              y--;
 64              delta=365;
 65          }
 66          for(int yit=year; yit<y+1; yit++)
 67          {
 68              if( IsLeapYear(yit) )
 69              {
 70                  delta--;
 71              }
 72          }
 73  
 74          if( IsLeapYear(y) )
 75          {
 76              monthDay[2-1]=29;
 77          }
 78          while(delta>0)
 79          {
 80              if( delta>monthDay[m-1] )
 81              {
 82                  delta=delta-monthDay[m-1];
 83                  
 84                  m= ++m==13?12:m;
 85                  y++;
 86                  if( IsLeapYear(y) )
 87                  {
 88                      monthDay[2-1]=29;
 89                  }
 90                  else
 91                  {
 92                      monthDay[2-1]=28;
 93                  }
 94  
 95              }
 96              else
 97              {
 98                  if( delta>monthDay[m-1]-d)
 99                  {
100                      d=delta-(monthDay[m-1]-d);
101                      m= ++m==13?12:m;
102                  }
103                  else
104                  {
105                      d=d+delta;
106                  }
107                  delta=0;
108              }
109          }
110          cout<<setfill('0')<<setw(4)<<y<<"/"<<setw(2)<<m<<"/"<<setw(2)<<d<<" ";
111  
112          //hr
113          delta=D[i];
114          y=year;
115          m=month;
116          d=day;
117          y=year-delta/365;
118          delta=delta-delta/365*365;
119          if( delta==0 )
120          {
121              y++;
122              delta=365;
123          }
124          for(int yit=year; yit>y; yit--)
125          {
126              if( IsLeapYear(yit) )
127              {
128                  delta--;
129              }
130          }
131          if( IsLeapYear(y) )
132          {
133              monthDay[2-1]=29;
134          }
135          while(delta>0)
136          {
137              if( m>1 )
138              {
139                  days=monthDay[(m-1)-1];
140              }
141              else
142              {
143                  days=monthDay[12-1];
144              }
145              if( delta>days )
146              {
147                  delta=delta-days;
148  
149                  m= --m==0?12:m;
150                  y--;
151                  if( IsLeapYear(y) )
152                  {
153                      monthDay[2-1]=29;
154                  }
155                  else
156                  {
157                      monthDay[2-1]=28;
158                  }
159  
160              }
161              else
162              {
163                  if( delta>d )
164                  {
165                      d=days-(delta-d);
166                      m= --m==0?12:m;
167                  }
168                  else
169                  {
170                      d=d-delta;
171                  }
172                  delta=0;
173              }
174          }
175          cout<<setfill('0')<<setw(4)<<y<<"/"<<setw(2)<<m<<"/"<<setw(2)<<d<<endl;
176  
177      }
178      return 0;
179  }

 

  算法先抛开不谈,我们先谈谈编写过程中遇到的种种知识遗忘点:

  1.include<> 声明头文件,有的时候写iostream,有的时候写iostream.h,有什么区别呢?

   我搜索这个问题,找到一篇解释较为详尽的博客:http://www.blogjava.net/hijackwust/archive/2008/06/20/209529.html

  简要解释如下:include<iostream.h>是C风格的,include<iostream>是C++风格的。前者会将标准库中的函数作为全局函数,而后者则是将标准库中的函数放入名字空间std中。名字空间namespace是C++标准委员会在1998年标准化之后引入的概念,这是因为:标准库涵盖范围很广,里面的类、函数很多,这就可能会与第三方提供的程序库中的类或函数发生名字冲突,有了名字空间,标准库中的东西就都放在了namespace std中了。iostream.h是98年之前的C++标准,应该被淘汰,只是因为编译器厂商利益才苟延残喘,严格说应是编译错误的。其他有一些*.h的头文件保留是为了对C兼容。

  另外,后续程序为了书写方便,经常会加上using namespace std; 这样后面用标准库的函数就可以直接写了。

  2.C++输出流的格式控制,如何将2显示为02呢?

  又是基础知识,参考博客为:http://blog.csdn.net/virtualdesk/article/details/5355793

  有两种方式控制输出格式:一是用控制符,二是用流对象的成员函数。下面给个控制符的示例。以小数形式,保留三位小数输出:

cout<<setprecision(3)<<setiosflags(ios::fixed)<<3.1415926<<endl;

  3.求模是什么符号?(我一直用坑爹的整数除法乘法 x/400*400)简单的判断语句可以不用if...else...而更简洁吗?各运算符优先级怎样的,以便减少圆括号?

  这是一大波C++特殊符号问题,参考博客为:http://blog.csdn.net/shencaifeixia1/article/details/7831134

  第二个问题的答案是:条件运算符 ? : 

  我后续改进也用到了它,如

m= --m==0?12:m;

  这里还要注意一点是关于自减运算符的,--m是先自减再做其他运算,而m--是先做其他运算再自减。前者是正确的写法,因为--是右结合的单目运算符,而后者是通过运算符重载而加入C++的。就像博客里说的:“另外在C语言里 没有前置后置之分 因为++ -- 是右结合所以 右侧优先运算 表现为 "后置优先级比较高" 的假象 前置和后置的区分是因为运算符重载而后加入C++的。”

 

  先说这么多,该睡了,明天继续。

posted @ 2013-03-25 02:59  Henry要当小码农  阅读(281)  评论(0编辑  收藏  举报