A - AD 2020 Gym - 102770A补体

2020 is the current year and is a leap year starting on Wednesday of the Gregorian calendar, the 2020th year of the Common Era (CE) and Anno Domini (AD) designations, the 20th year of the 3rd millennium, the 20th year of the 21st century, and the 1st year of the 2020s decade.

2020 has been designated as Year of the Nurse and Midwife by the World Health Organization. The United Nations has declared 2020 as the International Year of Plant Health. 2020 has been designated as International Year of Sound by the International Commission for Acoustics.

Because there are so many unforgettable things happening in 2020, somebody has now proposed that all dates with a substring containing “202” to be designated as the Day for Disaster Reduction. We represent a date in the format YYYYMMDD (for example, 21110202), then if 202 is a substring of this date, this day is the Day for Disaster Reduction.

Please write a program to compute how many Days for Disaster Reduction are there in all the dates between Y1Y1M1M1D1D1 and Y2Y2M2M2D2D2 (both inclusive)? Note that you should take leap years into consideration. A leap year is a year that can be divided by 400 or can be divided by 4 but can’t be divided by 100. A leap year has 2929 days in February, instead of the normal 2828 days.

Input
The input contains multiple cases. The first line of the input contains a single positive integer TT (1≤T≤1051≤T≤105), the number of cases.

The first and only line of each case contains six integers Y1,M1,D1,Y2,M2,D2Y1,M1,D1,Y2,M2,D2, which are described in the problem statement above.

It’s guaranteed that Y1Y1M1M1D1D1 is not larger than Y2Y2M2M2D2D2. Both Y1Y1M1M1D1D1 and Y2Y2M2M2D2D2 are between 20000101 and 99991231, and both dates are valid.

We kindly remind you that the size of the input and output of this problem can be large, so it’s recommended to use a faster I/O method. For example, in C++, you can use scanf/printf instead of cin/cout.

Output
For each case, print a single line containing a single integer, the answer.
题意:给你两个年月日,问你在这之间年月日有202的有几天;
废话不多说直接上代码,思路在注释里

#include
#include <bits/stdc++.h>
#define lowbite(x)(x&(-x))//用来计算二进制数最低位1后面的0组成的数字;
// 新学的一个函数:lower_bound(数组要查找的第一个数字的位置,末尾数字的位置,要查找的数值) 函数返回区间内要查找的数值第一个出现的位置
//函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置.
//注意:如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!
//相对的还有 upper_bound返回第一个大于待查找数值出现的位置
//功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置
//注意:返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置。同样,如果val大于数组中全部元素,返回的是last。(注意:数组下标越界)
//binary_search(,)返回是否存在这么一个数,是一个bool值
using namespace std;
int a[10004];
int num[11];
int mon[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int sum[10004];
int main()
{
int y = 2000, m = 1, d = 1;
while(1)//从2000年开始,一直到9999年计算每年有多少天中有202;
{
num[1] = y/1000;//年份第一位
num[2] = (y%1000)/100;//第二位
num[3] = (y%100)/10;//第三位;
num[4] = y % 10;//第四位
num[5] = m/10;//月份第一位
num[6] = m%10;//月份第二位;
num[7] = d / 10;//日子第一位;
num[8] = d%10;
for(int i = 1; i<=6; i++)
{
if(num[i]2&&num[i+1]0&&num[i+2]2)
{
sum[y]++;
break;
}
}
d++;
if(m
2&&((y%4
0&&y%100!=0)||y%400
0))
mon[2]=29;
else if(m2)
mon[2] = 28;
if(d>mon[m])
{
d = 1;
m++;
}
if(m>12)
{
y++;
sum[y] = sum[y-1];//sum存的是y以及y之前年份所有的天数,即一种前缀和
m=1;
}
if(y
10000)break;
}
int t;
scanf("%d",&t);
while(t–)
{
int y1, m1, d1, y2, m2, d2;
scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
int ans = sum[y2 - 1] - sum[y1];
y = y1;
m = m1;
d = d1;
while(1)
{
num[1] = y/1000;
num[2] = (y%1000)/100;
num[3] = (y%100)/10;
num[4] = y % 10;
num[5] = m/10;
num[6] = m%10;
num[7] = d / 10;
num[8] = d%10;
for(int i = 1; i<=6; i++)
{
if(num[i]2&&num[i+1]0&&num[i+2]2)
{
ans++;
break;
}
}
d++;
if(m
2&&((y%4
0&&y%100!=0)||y%400
0))
mon[2] = 29;
else if(m==2)
mon[2] = 28;
if(d>mon[m])
{
d=1;
m++;
}
if(m>12)
{
y++;
m = 1;
}
if(y == y1+1) break;

    }
    y = y2;
    m = 1;
    d = 1;
    while(1)
    {
        num[1] = y/1000;
        num[2] = (y%1000)/100;
        num[3] = (y%100)/10;
        num[4] = y % 10;
        num[5] = m/10;
        num[6] = m%10;
        num[7] = d / 10;
        num[8] = d%10;
        for(int i = 1; i<=6; i++)
        {
            if(num[i]==2&&num[i+1]==0&&num[i+2]==2)
            {
                ans++;
                break;
            }
        }
        if(y==y2&&m==m2&&d==d2) break;
        d++;
        if(m==2&&((y%4==0&&y%100!=0)||y%400==0))
            mon[2] = 29;
        else if(m==2)
            mon[2] = 28;
        if(d>mon[m])
        {
            d=1;
            m++;
        }
        if(m>12)
        {
            y++;
            m = 1;
        }
    }
    printf("%d\n",ans);
}
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值