If we represent a date in the format YYYY-MM-DD (for example, 2017-04-09), do you know how many 9s will appear in all the dates between Y1-M1-D1 and Y2-M2-D2 (both inclusive)?
Note that you should take leap years into consideration. A leap year is a year which can be divided by 400 or can be divided by 4 but can't be divided by 100.
Input
The first line of the input is an integer T (1 ≤ T ≤ 105), indicating the number of test cases. Then T test cases follow. For each test case:
The first and only line contains six integers Y1, M1, D1, Y2, M2, D2, their meanings are described above.
It's guaranteed that Y1-M1-D1 is not larger than Y2-M2-D2. Both Y1-M1-D1 and Y2-M2-D2 are between 2000-01-01 and 9999-12-31, and both dates are valid.
We kindly remind you that this problem contains large I/O file, so it's recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.
Output
For each test case, you should output one line containing one integer, indicating the answer of this test case.
Sample Input
4 2017 04 09 2017 05 09 2100 02 01 2100 03 01 9996 02 01 9996 03 01 2000 01 01 9999 12 31
Sample Output
4 2 93 1763534
Hint
For the first test case, four 9s appear in all the dates between 2017-04-09 and 2017-05-09. They are: 2017-04-09 (one 9), 2017-04-19 (one 9), 2017-04-29 (one 9), and 2017-05-09 (one 9).
For the second test case, as year 2100 is not a leap year, only two 9s appear in all the dates between 2100-02-01 and 2100-03-01. They are: 2017-02-09 (one 9) and 2017-02-19 (one 9).
For the third test case, at least three 9s appear in each date between 9996-02-01 and 9996-03-01. Also, there are three additional nines, namely 9996-02-09 (one 9), 9996-02-19 (one 9) and 9996-02-29 (one 9). So the answer is 3 × 30 + 3 = 93.
思路简要分析:听说可以用三维数组a[year][month][day]表示年月日,打表然后直接做减法,我没试过,但是我感觉这种方法需要把每天都打出来效率可能会低一些(个人猜测,作为萌新实力不济),我是打年和月的表,再分类计算,代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
int amount(int n);
int check(int year);
void change(int symbol) ;
void refresh();
long long year[10000]={0};
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int month[13]={0,3,2,3,3,3,3,3,3,3+30,3,3,3}; //月份打表
int main()
{
int T;
int i;
year[1999]=0;
for(i=2000;i<=9999;i++)
{
if(check(i))
year[i]=36+366*amount(i)+30;
else
year[i]=35+365*amount(i)+30; //年份打表
year[i]+=year[i-1];
}
scanf("%d",&T);
while(T--)
{
int year1,month1,day1;
int year2,month2,day2;
scanf("%d%d%d",&year1,&month1,&day1);
scanf("%d%d%d",&year2,&month2,&day2);
int i1;
long long sum=0;
int y1n=amount(year1);
int y2n=amount(year2); //判断该年几个9
if(year2-year1>=1) //不同年
{
sum+=year[year2-1]-year[year1];
int i1;
int data=0;
change(check(year1)); //判断平闰年决定2月的值
for(i1=month1+1;i1<=12;i1++)
{
sum+=month[i1];
data+=days[i1];
}
sum+=data*y1n;
//↑year1月份计算
refresh();
data=0; //数据恢复
// ↓year2月份计算
change(check(year2)); //判断平闰年决定2月的值
for(i1=month2-1;i1>=1;i1--)
{
sum+=month[i1];
data+=days[i1];
}
sum+=data*y2n;
refresh();
data=0;
//↓year1日的计算
change(check(year1)); //判断平闰年决定2月的值
for(i1=day1;i1<=days[month1];i1++)
{
if(month1==9)
sum++;
if(i1%10==9)
sum++;
sum+=y1n;
}
refresh(); //数据恢复
//↓year2日期的计算
change(check(year2));
for(i1=day2;i1>=1;i1--)
{
if(month2==9)
sum++;
if(i1%10==9)
sum++;
sum+=y2n;
}
refresh();
}
else //同年
{
if(month2-month1>=1) //不同月
{
change(check(year1));
for(i1=month1+1;i1<month2;i1++)
sum+=days[i1]*y1n+month[i1]; //月份计算
for(i1=day1;i1<=days[month1];i1++)
{
if(month1==9)
sum++;
if(i1%10==9)
sum++;
sum+=y1n;
}
//
for(i1=day2;i1>=1;i1--)
{
if(month2==9)
sum++;
if(i1%10==9)
sum++;
sum+=y1n;
}
//
refresh();
}
else //同月
{
if(check(year1))
{
month[2]++;
days[2]++;
}
for(i1=day1;i1<=day2;i1++)
{
if(month1==9)
sum++;
if(i1%10==9)
sum++;
sum+=y1n;
}
month[2]++;
days[2]++;
}
}
printf("%lld",sum);
if(T!=0)
printf("\n");
}
return 0;
}
int amount(int n) //判断年份里有几个9
{
int sum=0;
while(n>0)
{
if(n%10==9)
sum++;
n=n/10;
}
return sum;
}
int check(int year) //判断是否为闰年
{
if(year%400==0 ||(year%4==0 && year%100!=0))
return 1;
return 0;
}
void change(int symbol) //如果为闰年,修改2月份的值
{
if(symbol==1)
{
month[2]++;
days[2]++;
}
}
void refresh() //数据恢复函数
{
month[2]=2;
days[2]=28;
}