题目F1. Promising String (easy version)
题意:已知连续的两个 “ - ” 可转换成一个 " + ",求给定字符串有多少个区间,满足区间内的 “ - ” 和 “ + ” 的数量相等。
思路:由题意可得字符串中只会包含字符 “ - ” 和 “ + ” 两种字符,假设某一区间内的字符 “ - ” 的个数 为 q q q ,字符 “ + ” 的个数为 p p p ,若此区间满足条件 " - " 的数量与 “ + ” 的数量相等则
- q = = p q == p q==p
- ( q − p ) m o d 3 = = 0 (q - p)\text{ }mod\text{ }3 == 0 (q−p) mod 3==0
如果 q − p > 1 q - p > 1 q−p>1 则多出来的字符 “ - ” 定存在连续,又因为连续的两个 “ - ” 可转换为一个 “ + ” ,所以当 ( q − p ) m o d 3 = = 0 (q - p)\text{ }mod\text{ }3 == 0 (q−p) mod 3==0 成立时,区间符合要求。
如何快速的求解出区间中 “ - ” 和 “ + ” 的数量?可以使用前缀和相减n n n 的值不超过 3000 3000 3000,所以可用时间复杂度为 O ( N 2 ) O(N^2) O(N2) 的暴力解题法。
#include<stdio.h>
#include<string.h>
const int N = 1e5 + 10;
char s[N];
int sub[N],add[N];
int main(){
int t;
scanf("%d",&t);
while(t --) {
int n;
scanf("%d %s",&n,s+1);
for(int i=1;i<=n;i++) {
sub[i] = sub[i-1];
add[i] = add[i-1];
if(s[i] == '-') sub[i] ++;
else add[i] ++;
}
int cnt = 0;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
int k1 = sub[j] - sub[i-1];
int k2 = add[j] - add[i-1];
if(k2 > k1) continue;
else if(k1 == k2) cnt ++;
else if((k1 - k2) % 3 == 0) cnt ++;
}
}
printf("%d\n",cnt);
}
return 0;
}