2019牛客网暑假多校训练第四场 K —number

链接:https://ac.nowcoder.com/acm/contest/884/K
来源:牛客网

题目描述

300iq loves numbers who are multiple of 300.
One day he got a string consisted of numbers. He wants to know how many substrings in the string are multiples of 300 when considered as decimal integers.
Note that leading and trailing zeros are allowed (both in original string and substrings you chose) and the same substring appearing in different places can be counted multiple times.

输入描述:

A single line consisting a string consisted of characters '0' to '9'.

输出描述:

The number of substrings that are multiples of 300 when considered as decimal integers.


题解:首先我们分析满足条件的情况:能被300整除的子串
   1.串的最后两位肯定为00
   2.前面的各位和肯定能整除以3
   
   所以我们可以 开一个变量 sum, 记录下 ”前i位的和 mod 3 的情况“。 情况有三种:sum==0,sum==1,sum==2
   再开一个数组 cnt[],记录下 ”前i为的和 mod 3 的情况 出现的次数“。也就是只记录 cnt[0],cnt[1],cnt[2]
   
   为什么要记录 1和2的情况呢?举个例子:
   在[L,R]的区间中,如果 在L处的sum 和 在R处的sum相等的话,那么就意味着 L~R的数位和 mod 3 == 0.也就是[L,R]为一个能整除3的子串。
   
   
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize(2)
//#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include<fstream>
#include<sstream>
#include<iterator>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<list>
#include<set>

using namespace std;
typedef double dou;
typedef long long ll;
typedef pair<int, int> pii;
typedef map<int, int> mii;

#define pai acos(-1.0)
#define M 100005
#define inf 0x3f3f3f3f
#define mod 1000000007
#define left k<<1
#define right k<<1|1
#define lson L, mid, left
#define rson mid + 1, R, right
#define W(a) while(a)
#define ms(a,b) memset(a,b,sizeof(a))
#define Abs(a) (a ^ (a >> 31)) - (a >> 31)

char str[M];
int cnt[M];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    W (cin>>str) {        
        ll ans = 0;
        int len = strlen(str);
        for (int i = 0; i < len; i++) {
            if (str[i] == '0') ans++;//先统计单个0的情况
        }
        cnt[0] = 1;
        int sum = 0;//前i位mod 3的值
        for (int i = 0; i < len; i++) {
            sum += str[i] - '0';
            sum %= 3;
            if (i + 1 < len && str[i] == '0' && str[i + 1] == '0') {//满足尾数为00 且在长度范围内
                ans += cnt[sum];
            }
            cnt[sum]++;//cnt[0] 、cnt[1]、cnt[2]
        }
        cout << ans << endl;
    }
    return 0;
}



猜你喜欢

转载自www.cnblogs.com/caibingxu/p/11258190.html