原题:http://acm.fzu.edu.cn/problem.php?pid=2014
总结:
1、闰年使用一般的公式进行判断,虽然题目不严谨没说清楚,但可以猜测不可能让我们去实现精确计算。
2、输出的年份不需要前导0,因为这点WA好久还找不出bug。按%4d输出即可。
试了这篇代码才知道的:http://www.cppblog.com/coreBugZJ/archive/2011/03/20/142304.html。
3、第一次知道%02d的格式,可以用2的域宽输出整型值,并用前导0进行填充。AC前我手动实现此功能,用到log10等数学函数计算位数,用VC++提交会CE。以后涉及log里数据类型为整型等不匹配情况,要么进行强制转换,要么用G++提交。
#include <iostream> #include <algorithm> using namespace std; const int Y = 1000; // 最多回到公元前1000年 int isleap(int y) {return (y%4==0)&&(y%100!=0)||y%400==0;} void init(int a[]) { a[Y+2013] = 11; // 2012年12月21日后过11天为2013 for(int i=Y+2012; i>=0; i--) // 计算出大约三千年的区间 a[i] = a[i+1]-365-isleap(i-Y); } int main() { int n, y, m, d, *p; int a[Y+2014]; // 下标为年份+Y int b[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; init(a); // 计算出每年的1月1日为2012.12.21后第几天(之前则为负值) while(cin >> n) { n = -n; p = upper_bound(a,a+Y+2013,n) - 1; // 二分查找,先找到对应年份 y = p - &a[Y]; // 获得年份y d = n - *p + 1; // 获得此为该年第几天 if(isleap(y)) b[2] = 29; else b[2] = 28; m = 0; while(d>b[m]) d -= b[m++]; // 计算出月份m和日期d printf("%4d-%02d-%02d\n", y, m, d); } return 0; }