问题A :A. Balanced Substring
题目大意
一个字符串s,由n个字母组成,每个字母要么是’a’, 要么是’b’,字符串中的字母从1到n编号。s[l, r]是从字符串的索引l到r的连续字母字串。如果字符串中’a’的数量大于’b’的数量,则该字符串被称为平衡字符串,查找字符串s中的任何非空平衡子字符串s[l, r]。打印其l和r,如果没有这样的子串,则打印-1 -1。
示例
输入
4
1
a
6
abbaba
6
abbaba
9
babbabbaa
输出
-1 -1
1 6
3 6
2 5
在第一个测试用例中没有非空的平衡子字符串。
在第二个和第三个测试用例中,有多个平衡的子字符串,包括整个字符串“abbaba”和子字符串“baba”。
思路1
找最短的平衡字符串,即一个’a’和相邻的’b’组成的平衡字符串,从头遍历字符串,如果存在,则打印最后一个平衡字符串的位置,否则打印-1 -1。
#include <cstdio>
using namespace std;
char s[110];
int n, t;
int main()
{
scanf("%d", &t);
while(t--)
{
int l = -1, r = -1;
scanf("%d%s", &n, s + 1);
for(int i = 1; i < n; i++)
if(s[i] != s[i + 1])
{
l = i;
r = i + 1;
}
printf("%d %d\n",l, r);
}
return 0;
}
思路2
找最长的平衡字符串。利用前缀和思想,sum初始值为0,遇’a’加1,遇’b’减1,用sum的值更新前缀和数组,两重循环,来判断是否有平衡字符串。如果有,则打印l和r,退出循环,如果没有,则打印-1 -1。
#include <iostream>
#include <cstdio>
using namespace std;
int t, n;
char s[60];
int pre[60];
int main()
{
cin >> t;
while(t--)
{
cin >> n >> s + 1;
int sum = 0;
for(int i = 1; i <= n; i++)
{
if(s[i] == 'a') sum++;
if(s[i] == 'b') sum--;
pre[i] = sum;
}
bool flag = false;
for(int i = n; i >= 1; i--)
{
for(int j = 0; j < i - 1; j++)
{
if(pre[i] == pre[j])
{
printf("%d %d\n", j + 1, i);
flag = true;
break;
}
}
if(flag == true) break;
}
if(flag == false) printf("-1 -1\n");
}
return 0;
}