2021牛客暑期多校训练营1 - F - Find 3-friendly Integers - 题解

Posted Tisfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021牛客暑期多校训练营1 - F - Find 3-friendly Integers - 题解相关的知识,希望对你有一定的参考价值。

2021牛客暑期多校训练营1 - F - Find 3-friendly Integers

传送门
Time Limit: 1 second
Memory Limit: 262144K

题目描述

A positive integer is 3-friendly if and only if we can find a continuous substring in its decimal representation, and the decimal integer represented by the substring is a multiple of 3 3 3.

For instance:
104 {104} 104 is 3-friendly because “0” is a substring of “104” and 0 m o d    3 = 0 0 \\mod 3 = 0 0mod3=0.
124 {124} 124 is 3-friendly because “12” is a substring of “124” and 12 m o d    3 = 0 12 \\mod 3 = 0 12mod3=0. “24” is also a valid substring.
17 {17} 17 is not 3-friendly because 1 m o d    3 ≠ 0 ,   7 m o d    3 ≠ 0 ,   17 m o d    3 ≠ 0 1 \\mod 3 \\ne 0, ~7 \\mod 3 \\ne 0, ~17 \\mod 3 \\ne 0 1mod3=0, 7mod3=0, 17mod3=0.

Note that the substring with leading zeros is also considered legal.

Given two integers L {L} L and R {R} R, you are asked to tell the number of positive integers x {x} x such that L ≤ x ≤ R L \\le x \\le R LxR and x {x} x is 3-friendly.

输入描述:

There are multiple test cases. The first line of the input contains an integer T ( 1 ≤ T ≤ 10000 ) T(1 \\le T \\le 10000) T(1T10000), indicating the number of test cases. For each test case:

The only line contains two integers L , R ( 1 ≤ L ≤ R ≤ 1 0 18 ) L,R(1 \\le L \\le R \\le 10^{18}) L,R(1LR1018), indicating the query.

输出描述:

For each test case output one line containing an integer, indicating the number of valid x {x} x.

样例

样例一

输入

3
4 10
1 20
1 100

输出

3
11
76

题目大意

给你两个数 L L L R R R,问从 L L L R R R的所有数中:

  • 这个数十进制状态下的字符串的所有子串中,有某个子串是3的倍数

的数有多少个。

解题思路

  • 十进制下,某个数的每一位之和是3的倍数,则这个数是3的倍数。
  • 所有长度≥3的数中,都能找到一个子串是3的倍数。

比如长度为3的一个数 a b c abc abc,假如 a % 3 = 0 a\\%3=0 a%3=0 a a a就是3的倍数。
假如 a % 3 = 1 a\\%3=1 a%3=1,那么 b % 3 b\\%3 b%3不能等于2,也不能等于0。等于0则 b b b就直接是3的倍数,等于 2 2 2 ( a + b ) % 3 = 0 (a+b)\\%3=0 (a+b)%3=0 a b ab ab就是3的倍数。因此 b % 3 必 须 是 1 b\\%3必须是1 b%31,因此 c % 3 c\\%3 c%3无论是 0 , 1 0,1 0,1还是 2 2 2,都能找到 3 3 3的倍数。
假如 a % 3 = 2 a\\%3=2 a%3=2,同样能证明。

因此我们只需要找0~99(1位数和2位数)中,有多少个数不能找到一个子串能被3整除就可以了。只有100个数,方法随意,不会超时。


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
bool bg[105];
bool ifis(int n) // 是不是能找到一个子串能整除3
{
    if(n%3==0)return true; // 本来就能整除3
    if(n>9&&(n/10)%3==0)return true; // 是两位数并且十位是3的倍数
    if((n%10)%3==0)return true; // 个位能整除3
    return false; // 以上方法都不能
}
int main()
{
    for(int i=0;i<100;i++) // 先预处理0~99这100个数
    {
        bg[i]=ifis(i);
    }
    int n;
    cin>>n;
    while(n--)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        ll ans=0;
        if(a<100) // 如果从小于100的数开始
        {
            for(int i=a;i<=min(b,100LL);i++) // 小于100的部分遍历一遍看看有几个
            {
                ans += bg[i];
            }
            if(b>=100) // 如果R大于等于100,大于等于100的部分每个都是
            {
                ans+=b-99;
            }
        }
        else
        {
            ans=b-a+1; // 否则L大于等于100,L到R的所有数都能找到3的倍数
        }
        printf("%lld\\n",ans); // 输出结果
    }
    return 0;
}

原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/118858197

以上是关于2021牛客暑期多校训练营1 - F - Find 3-friendly Integers - 题解的主要内容,如果未能解决你的问题,请参考以下文章

2021牛客暑期多校训练营1

2021牛客暑期多校训练营4 B.Sample Game(期望平方递推)

2021牛客暑期多校训练营8 F.Robots 离线分治+bitset

2021牛客暑期多校训练营3 F.24dian 暴搜dfs

2021牛客暑期多校训练营1 I.Increasing Subsequence(期望,维护后缀和优化dp)

2021牛客暑期多校训练营1 Alice and Bob(结论,sg打表|优化)