codeforces 676C Vasya and String 贪心 尺取法
题目链接:http://codeforces.com/contest/676/problem/C
题意:
给出一个长度为n的字符串,只有字符'a'和'b'。最多能改变k个字符,即把'a'变成'b'或把'b'变成'a'。
问改变后的最长连续相同字符的字串长度为多少。
思路:
因为要使连续的相同字符最多,所以改变的字符肯定相同的,靠近的。
比如17 3
aaabbaabaaaabbbaa
如果改变b,那么改变的肯定是第1,2,3的b或第2,3,4的b或第3,4,5的b.....
所以然后就尺取法做就可以了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, k; 4 #define maxn 100010 5 char s[maxn]; int len; 6 struct Node 7 { 8 int l, r; 9 void clear() {l = 0; r = 0;} 10 }a[maxn]; 11 int cnt; 12 int slove(char c) 13 { 14 int sum = 0; cnt = 0; 15 if(s[0] == c) {a[cnt].l = 0; cnt++; sum = 0;} 16 else sum = 1; 17 for(int i = 1; i < len; i++) 18 { 19 if(s[i] == c){ a[cnt].l = sum; sum = 0; cnt++;} 20 else sum++; 21 } 22 23 int tcnt = cnt-1; 24 if(s[len-1] == c) {a[tcnt].r = 0; tcnt--; sum = 0;} 25 else sum = 1; 26 for(int i = len-2; i >= 0; i--) 27 { 28 if(s[i] != c) sum++; 29 else if(s[i] == c) {a[tcnt].r = sum; sum = 0; tcnt--;} 30 } 31 32 int L = 0, R = k-1; 33 int ans = 0; 34 for(int i = L; i <= min(R, cnt-1); i++) ans += a[i].l; 35 ans += a[min(R, cnt-1)].r; ans += min(k, cnt); sum = ans; 36 while(L <= cnt-k-1) 37 { 38 sum -= a[L].l; sum += a[R+1].r; 39 L++; R++; 40 ans = max(sum, ans); 41 } 42 return ans; 43 } 44 int main() 45 { 46 //freopen("in.txt", "r", stdin); 47 //freopen("out.txt", "w", stdout); 48 while(~scanf("%d%d", &n, &k)) 49 { 50 scanf("%s", s); len = strlen(s); 51 if(k == 0) 52 { 53 int ans = 0, sum = 0; char prec = '#'; 54 for(int i = 0; i < len; i++) 55 { 56 if(s[i] != prec) {prec = s[i]; ans = max(ans, sum); sum = 1;} 57 else sum++; 58 } 59 ans = max(ans, sum); 60 printf("%d\n", ans); continue; 61 } 62 int sum = 0; 63 for(int i = 1; i < len; i++) 64 { 65 if(s[i] == s[0]) sum++; 66 } 67 if(sum == len-1) printf("%d\n", len); 68 else printf("%d\n", max(slove('a'), slove('b'))); 69 } 70 return 0; 71 }