Codeforces Round #442 (Div. 2) B. Nikita and string 题解

来源:互联网 发布:淘客网页源码 编辑:程序博客网 时间:2024/05/21 02:51

题目链接:http://codeforces.com/contest/877/problem/B


大意:一串由abc三个字母组成的字符串,要求不破坏各个字符的先后顺序,移除一些字母,得到如下先后三段,第一第三段由a组成,第二段由b组成,这三段可为空,这样的三段所组成的最长长度。


分析:首先离散地统计各个小的段,比如一个串为abbaaba,那么就可以分为五段,每段长度分别为1 2 2 1 1,之后我们枚举一个由b组成的区间,比如这里可以用第二小段和第四小段组成,这样便可以确定了题目中要求的那个第二段。之后在区间的基础上向前向后分别取得可以得到的最长的,由a组成的段,这样便可以得到一个O(n^4)的算法,在进行最后一步向前向后寻找a组成的段时,我们也可以进行预处理,求得每段到某一个小段为止,前面的有多少个a,后面的有多少个a。


代码:

#include  <iostream>#include  <cstdio>#include  <cstring>using namespace std;const int maxn = 5005;char s[maxn];int ans, len[maxn], sum1[maxn], sum2[maxn], length, cnt;char op[maxn];int main() {scanf("%s", s);memset(sum1, 0, sizeof(sum1));memset(sum2, 0, sizeof(sum2));memset(len, 0, sizeof(len));memset(op, 0, sizeof(op));cnt = 0;length = 1;for(int i = 0; i < strlen(s); i++) {if(s[i] != s[i + 1]) {cnt++;op[cnt] = s[i];len[cnt] = length;length = 1;} else {length++;}}if(op[1] == 'a') {sum1[1] = len[1];} else {sum1[1] = 0;}for(int i = 2; i <= cnt; i++) {if(op[i] == 'a') {sum1[i] = sum1[i - 1] + len[i];} else {sum1[i] = sum1[i - 1]; }}if(op[cnt] == 'a') {sum2[cnt] = len[cnt];} else {sum2[cnt] = 0;}for(int i = cnt - 1; i >= 1; i--) {if(op[i] == 'a') {sum2[i] = sum2[i + 1] + len[i];} else {sum2[i] = sum2[i + 1];}}ans = 0;bool tag = false;for(int i = 1; i <= cnt; i++) {for(int j = i; j <= cnt; j++) {if(op[i] == 'b' && op[j] == 'b') {tag = true;int sum = 0;for(int k = i; k <= j; k++) {if(op[k] == 'b') {sum +=len[k];}}sum += sum1[i];sum += sum2[j];if(sum > ans) {ans = sum;}}}}if(!tag) {ans = strlen(s);}printf("%d\n", ans);return 0;}

阅读全文
1 0
原创粉丝点击