zoj3950-How Many Nines
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 thanY
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.
做這種題最好就是f(b)-f(a-1)這樣子算一次。然後打表。
這道題我卡了兩次,不知道是掛在輸入上還是掛在cout上,於是我果斷寫了讀入掛,就AC了。
#include <stdio.h>
#include <string.h>
#include <ctime>
#include <stack>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <ctime>
#include <queue>
#include <vector>
using namespace std;
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lowbit(x) (x&-x)
const int maxn = 1e6+5;
const int INF = 0x3f3f3f3f;
int s[366*8005];
int yd[10005];
bool isRun(int year)
{
if(year%100==0)
{
if(year%400==0)
return true;
}
else if(year%4==0)
return true;
return false;
}
void del(int& year,int& month,int& day)
{
int a[] ={31,31,28,31,30,31,30,31,31,30,31,30,31};
if(isRun(year)) a[2]++;
day--;
if(day==0)
{
day = a[month-1];
month--;
if(month==0)
{
month = 12;
year--;
}
}
}
int getNum(int year)
{
int ret = 0;
while(year)
{
if(year%10==9) ret++;
year/=10;
}
return ret;
}
void init()
{
for(int i=2000; i<=9999; i++)
if(isRun(i))
yd[i] = yd[i-1]+getNum(i)*366+36+30;
else
yd[i] = yd[i-1]+getNum(i)*365+35+30;
}
int f(int year,int month,int day)
{
int a[] ={31,31,28,31,30,31,30,31,31,30,31,30,31};
if(isRun(year)) a[2]++;
if(year<2000) return 0;
int ret = yd[year-1];
ret += (month-1)*3;
if(month>2&&!isRun(year)) ret--;
if(day>=9&&day<19)
ret++;
else if(day>=19&&day<29)
ret+=2;
else if(day>=29)
ret+=3;
int dat = 0;
for(int i=1; i<month; i++)
dat += a[i];
dat+=day;
ret += getNum(year)*dat;
if(month>9)
ret += 30;
else if(month==9)
ret += day;
return ret;
}
int readint()
{
int ret = 0;
char c = getchar();
while (c<'0' || c>'9') c = getchar();
while (c >= '0'&&c <= '9')
{
ret = ret * 10 + c - '0';
c = getchar();
}
return ret;
}
int main()
{
int T;
init();
scanf("%d",&T);
while(T--)
{
int y1,y2,m1,m2,d1,d2;
y1 = readint();
m1 = readint();
d1 = readint();
y2 = readint();
m2 = readint();
d2 = readint();
del(y1,m1,d1);
printf("%d\n",f(y2,m2,d2)-f(y1,m1,d1));
}
return 0;
}