日期问题模版ZOJ Problem Set -3950 How Many NinesZOJ 找9

来源:互联网 发布:深圳少儿编程培训 编辑:程序博客网 时间:2024/06/06 18:16

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3950

ZOJ Problem Set - 3950
How Many NinesZOJ 

Time Limit: 1 Second      Memory Limit: 65536 KB

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 betweenY1-M1-D1 andY2-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. ThenT 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 thanY2-M2-D2. BothY1-M1-D1 andY2-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.

题意:给两个日期,找之间出现多少个9;思路:打表预处理:

AC代码:

#include<bits/stdc++.h>using namespace std;int st[10000][15][33];int en[10000][15][33];int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};bool isLeap(int y){    if(y%400 == 0 || (y%4==0 && y%100 != 0))        return true;    return false;}void init(){    int cnt = 0;    for(int y=2000;y<=9999;y++)    {        int m = 1, d = 1, tmp = y, cnty = 0;        while(tmp)            cnty += tmp%10==9?1:0,  tmp/=10;        while(true)        {            st[y][m][d] = cnt;            cnt += cnty + (m==9?1:0) + (d%10==9?1:0);            en[y][m][d] = cnt;            d++;            if(m==12 && d == 32)    break;            if(isLeap(y) && m==2 && d==29)  continue;            if(d > mon[m])  m++,    d = 1;        }    }}int main(){    init();    int T, sy, sm, sd, ey, em, ed;    scanf("%d",&T);    while(T--)    {        scanf("%d %d %d %d %d %d", &sy, &sm, &sd, &ey, &em, &ed);        printf("%d\n", en[ey][em][ed] - st[sy][sm][sd]);    }}
















0 0