整理的算法模板:ACM算法模板總結(分類詳細版)
D - Multiple of 2019
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 400400 points
Problem Statement
Given is a string SS consisting of digits from 1
through 9
.
Find the number of pairs of integers (i,j)(i,j) (1≤i≤j≤|S|1≤i≤j≤|S|) that satisfy the following condition:
Condition: In base ten, the ii-th through jj-th characters of SS form an integer that is a multiple of 20192019.
Constraints
- 1≤|S|≤2000001≤|S|≤200000
- SS is a string consisting of digits from
1
through9
.
Input
Input is given from Standard Input in the following format:
SS
Output
Print the number of pairs of integers (i,j)(i,j) (1≤i≤j≤|S|1≤i≤j≤|S|) that satisfy the condition.
Sample Input 1 Copy
Copy
1817181712114
Sample Output 1 Copy
Copy
3
Three pairs - (1,5)(1,5), (5,9)(5,9), and (9,13)(9,13) - satisfy the condition.
Sample Input 2 Copy
Copy
14282668646
Sample Output 2 Copy
Copy
2
Sample Input 3 Copy
Copy
2119
Sample Output 3 Copy
Copy
0
題意:求一個至多長爲20000的只包含1 ~ 9的字符串中有多少連續子串轉爲10進制後爲2019的倍數。
思路:
如果兩個數x,y 對同一個數(2019)取模的餘數相同,我們稱之爲同餘;x=2019*a+b y=2019*c+b 那麼x y之間的差值一定是2019的整數倍;
從字符串右端開始往左擴展整數;
每擴展一次就對x就行取模一次;如果出現兩個數的餘數相同就說明這兩個數之間存在2019的倍數;所以用一個數組或者map記錄之前每個餘數出現的次數,每個x與之前同餘的數間都可以構成2019的倍數,如果餘數爲0則x本身就可以作爲2019的倍數,所以map[0]初始化爲1。
#include <bits/stdc++.h>
using namespace std;
int sum[200005];
map<int,int> mp;
int main()
{
int ans=0;
string s;
cin >>s;
mp[0]=1;
int len=s.size(),x=0,cnt=1;
for(int i=len-1;i>=0;i--)
{
x=((s[i]-'0')*cnt+x)%2019;
ans+=mp[x];
mp[x]++;
cnt=cnt*10%2019;//注意這裏是上面對x取模的時候也對cnt進行了取模
}
cout <<ans<<endl;
}