number
Title Description
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.
Enter a description:
A single line consisting a string consisted of characters '0' to '9'.
Output Description:
The number of substrings that are multiples of 300 when considered as decimal integers.
Example 1
Remarks:
let the string in the input be s, 1 \leq |s| \leq 10^51≤∣s∣≤105.
To a string, I asked how many sub-divisible string 300, contains a leading zero.
dp [i] [j] denotes the number of number of% 300 == j formed in all positions before position i and
It may be pushed to the current state [i + 1] [(j * 10 + s [i + 1] - '0')% 300]
Therefore, the state transition equation dp [i] [(j * 10 + s [i] - '0')% 300] + = dp [i - 1] [j] .. Note that the initial value every time dp [i] [ s [i] - '0'] = 1.
#include<bits/stdc++.h> #define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl #define pii pair<int,int> #define clr(a,b) memset((a),b,sizeof(a)) #define rep(i,a,b) for(int i = a;i < b;i ++) #define pb push_back #define MP make_pair #define LL long long #define ull unsigned LL #define ls i << 1 #define rs (i << 1) + 1 #define INT(t) int t; scanf("%d",&t) using namespace std; const int maxn = 1e5 + 10; LL dp[maxn][310]; char s[maxn]; int main() { while(~scanf("%s",s + 1)){ int len = strlen(s + 1); clr(dp,0); for(int i = 1;i <= len;++ i){ int tmp = s[i] - '0'; dp[i][tmp] = 1; for(int j = 0;j < 300;++ j) dp[i][(j * 10 + tmp) % 300] += dp[i - 1][j]; } LL ans = 0; for(int i = 1;i <= len;++ i) ans += dp[i][0]; cout << ans << endl; } return 0; }
Of course, this problem may be to make a prefix and, apparently 300% == 0 requires two conditions, at the end of two 0 foregoing == 0 3%, it is possible to record a prefix before the current position and 3% == 0, 1, 2 number, then add the number corresponding to
#include<bits/stdc++.h> #define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl #define pii pair<int,int> #define clr(a,b) memset((a),b,sizeof(a)) #define rep(i,a,b) for(int i = a;i < b;i ++) #define pb push_back #define MP make_pair #define LL long long #define ull unsigned LL #define ls i << 1 #define rs (i << 1) + 1 #define INT(t) int t; scanf("%d",&t) using namespace std; const int maxn = 1e5 + 10; char s[maxn]; int sum[maxn]; int mp[maxn * 10]; int main() { while(~scanf("%s",s + 1)){ clr(mp,0); int sz = strlen(s + 1); LL ans = 0; for(int i = 1;i <= sz;++ i){ sum[i] = sum[i - 1] + s[i] - '0'; sum[i] %= 3; if(s[i] == '0') ++ ans; } for(int i = 1;i + 1 <= sz;++ i){ if(s[i] == '0' && s[i + 1] == '0'){ ++ ans; // printf("===>%d , ",mp[sum[i - 1]]); debug(sum[i - 1]); ans += mp[sum[i - 1]]; if(sum[i - 1] % 3 != 0) -- ans; } // debug(ans); ++ mp[sum[i]]; } // debug(ans); cout << ans << endl; } return 0; }