第一行输入一个整数
,表示字符串长度。
第二行输入一个长度为
且仅包含数字的字符串
。
在一行上输出输出一个整数,表示不同的删除方案数。
4 1233
7
如果选择进行操作,则可能删除的区间有:
●
,则剩余 "
" ,满足是
的倍数。
●
,剩余 "
" ,满足是
的倍数。
●
,剩余 "
" ,满足是
的倍数。
●
,剩余 "
" ,满足是
的倍数。
●
,剩余 "
" ,满足是
的倍数。
●
(全部删除)则剩余 "
" ,也满足是
的倍数。
● 不进行操作,则剩余 "
" ,也是
的倍数。
则共有七种删除方案(注意,不删除/全删除也是删除方案)。
首先,将数字串s能够分出一个数字数组nums = [a0, a1, a2, a3, ..., an-1],方便后续计算。
假设nums数组所有元素之和为sum,则sum % 3就代表整个数组多出来的值,只要能够减去这个值,那么剩余的数字就可以是3的倍数(顺便减去一些是3的倍数的区间,那么最终结果也是3的倍数。
从左到右遍历,presum代表[0, i-1]的所有元素的和,同时记录presum % 3出现的次数,假设i = 0时,presum = 0。
我们已经知道sum % 3的值是多少,因此,我们可以在presum中减去这个值。
此时sum - (sum % 3)剩余区间的元素之和的是3的倍数,因此组成的数字是3的倍数。
假设presum - (sum % 3)之后剩余区间叫做presum_remain。
若前面有和presum_remain相同的余数的presum,则也可以算作一种方案。
因此可以删除,余数为0的部分和sum % 3的部分,这也算一种方案。
最终,写出代码:
import sys
from collections import Counter
line = sys.stdin.readline().strip().split()
n = int(line[0])
a = sys.stdin.readline().strip()
nums = [0] * n
for i in range(n):
nums[i] = int(a[i])
m_sum = sum(nums)
cnt = Counter()
presum = 0
ans = 0
for i in range(n):
cnt[presum % 3] += 1
presum += nums[i]
ans += cnt[(presum - (m_sum % 3)) % 3]
if m_sum % 3 == 0:
ans += 1
print(ans)
#include <iostream>
#include <unordered_map>
using namespace std;
int dp[2*100001][3];
int main() {
int n;
string s;
long long ret=0;
cin >> n >> s;
int sum=0;
for(int i=0;i<n;++i){
sum+=s[i]-'0';
}
int left = sum%3;
dp[0][(s[0]-'0')%3] = 1;
for(int i =1;i<n;++i){
switch ((s[i]-'0')%3) {
case 0:
dp[i][0] = dp[i-1][0]+1;
dp[i][1] = dp[i-1][1];
dp[i][2] = dp[i-1][2];
break;
case 1:
dp[i][0] = dp[i-1][2];
dp[i][1] = dp[i-1][0]+1;
dp[i][2] = dp[i-1][1];
break;
case 2:
dp[i][0] = dp[i-1][1];
dp[i][1] = dp[i-1][2];
dp[i][2] = dp[i-1][0]+1;
break;
}
}
for(int i=0;i<n;++i){
ret+=dp[i][left];
}
if(left ==0)
ret++;
cout << ret << endl;
return 0;
} import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String s = sc.next();
int sum = 0;
for(int i = 0;i < n;i ++ ) {
sum += s.charAt(i) - '0';
}
Map<Integer, Integer> cnt = new HashMap<>();
int presum = 0;long res = 0;
for(int i = 1;i <= n;i ++ ) {
cnt.put(presum % 3, cnt.getOrDefault(presum% 3, 0) + 1);
presum += s.charAt(i - 1) - '0';
res += cnt.getOrDefault((presum - (sum % 3)) % 3, 0);
}
if(sum % 3 == 0) res ++;
System.out.println(res);
}
}