C

来源:互联网 发布:沈阳淘宝代运营 编辑:程序博客网 时间:2024/06/05 17:22

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 Y1M1D1Y2M2D2, 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
42017 04 09 2017 05 092100 02 01 2100 03 019996 02 01 9996 03 012000 01 01 9999 12 31
Sample Output
42931763534
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.



假如:时间sum1 到 sum2的9的个数。

思路,

  对于时间多的,(1)你可以写出来sum1中,sum1 - 01 - 01 到现在的sum1的9的个数。

                              (2)写出来sum2中,sum2 - 01 - 01 到现在的sum2的9的个数。

                              (3)写出年的相差中的9个个数,再去处理就可以了。

  对于时间少的,你可以去预处理。题目给出了时间间隔:2000-01-01 and 9999-12-31。

第一种方法坑点:(1)注意:9月是30*1+3个,

                                (2)年中含9。

第二种方法坑点:(1)年中含9。


其余的就没有了。最好是预处理,因为时间不够,这题,只有一秒。

超时代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;int n1,y1,r1,n2,y2,r2;int v1[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};int v[]= {0,3,3,3,3,3,3,3,3,33,3,3,3};int cmp(int n){    int k=0;    while(n)    {        int t = n%10;        if(t==9) k++;        n=n/10;    }    return k;}///相差的年的数目ll cha(){    int k1 = 0;    for(int i=n1; i<n2; i++)    {        if(i%4==0 && i%100!=0 || i%400==0)            k1+=11*3+33+cmp(i)*366;        else            k1+=10*3+2+33+cmp(i)*365;    }    return k1;}///该年01-01到先在的9的个数ll qian(int n1,int y1,int r1,int t){    int k=0;    if(n1%4==0 && n1%100!=0 || n1%400==0)    {        v[2] = 3;        v1[2]=29;    }    else    {        v[2] = 2;        v1[2]=28;    }    int rq1 =0;    for(int i =1; i<y1 ; i++)    {        k+=v[i];        rq1+=v1[i];    }    if(t==1)    {      r1-=1;    }    rq1 += r1;    k += rq1*cmp(n1);    if(r1%10==9)        k =k + r1/10+1;    else        k =k + (r1/10);    return k;}int main(){    int n;    scanf("%d",&n);    while(n--)    {        scanf("%d%d%d%d%d%d",&n1,&y1,&r1,&n2,&y2,&r2);        printf("%lld\n",cha()-qian(n1,y1,r1,1)+qian(n2,y2,r2,0));    }    return 0;}


01 到 31中一个数r1中含9的个数:r1/10+r1%10==9?1:0;你可以用29,31代入看看。

预处理的代码:
 

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;///思路存储。///把每一个都存起来。int ans[10000][13][32];int vis[]={0,31,28,31,30,31,30,31,31,30,31,30,31};///每一个数的9的个数int mei(int n){    int k=0;    while(n)    {        int t = n%10;        n=n/10;        if(t==9) k++;    }    return k;}void cmp(){    ///x表示年 y表示月 z表示日    int x=2000,y=1,z=1;    ll sum =0;    while(!(x==10000 && y==1 && z==1))    {        if(x%4==0 && x%100!=0 || x%400==0)            vis[2] = 29;        else            vis[2] = 28;        sum+=mei(x)+mei(y)+mei(z);        ans[x][y][z] = sum;        z++;        if(z>vis[y])        {            y++;            z=1;            if(y>12)            {                y=1;                x++;            }        }    }}int main(){    memset(ans,0,sizeof(ans));    ///预处理    cmp();    int T;    scanf("%d",&T);    while(T--)    {        int n1,n2,y1,y2,r1,r2;        scanf("%d%d%d%d%d%d",&n1,&y1,&r1,&n2,&y2,&r2);        printf("%d\n",ans[n2][y2][r2]-ans[n1][y1][r1]+ mei(n1)+ mei(y1) + mei(r1));    }    return 0;}

原创粉丝点击