题目链接:uva 11920 - 0 s, 1 s and ? Marks
题目大意:给出一个字符串,有1,0和?组成,?可以是0也可以是1,问说该字符串的最大连续字符数的最小值。
解题思路:0和1都好说,就是碰上?会难搞一点,被坑的很惨。当碰到?时,枚举出有多少个连续的?,分为奇数偶数讨论,特殊情况是1个的时候,如果前后两个字符是不同的,要比较前后的大小,选小的,相同优先选前一个。然后就是注意?开头的情况。
#include <stdio.h>
#include <string.h>
#define max(a, b) (a)>(b)?(a):(b)
const int N = 1005;
int len;
char str[N];
int handle(int& x, int& c, char& rec) {
int cnt = 0;
char ch = str[x];
while (x < len) {
if (str[x] == ch) cnt++;
else break;
x++;
}
x--;
int ans;
if (cnt >= c) {
ans = max(cnt, c+1);
c = cnt;
rec = ch;
} else {
ans = max(cnt+1, c);
c = cnt + 1;
rec = ch;
}
return ans;
}
int solve() {
len = strlen(str);
int ans = 1, c = 0;
char rec = '\0';
for (int i = 0; i < len; i++) {
if (str[i] == '?') {
int cnt = 0, flag = i;
while (i < len) {
if (str[i] == '?') cnt++;
else break;
i++;
}
if (i == len) ans = max(ans, c);
else if (cnt % 2) {
if (str[i] == rec) {
ans = max(ans, c);
rec = str[i]; c = 1;
} else {
if (cnt == 1) {
int t = handle(i, c, rec);
ans = max(ans, t);
} else {
if (flag) ans = max(ans, 2);
ans = max(ans, c);
rec = str[i]; c = 1;
}
}
} else {
ans = max(ans, c);
if (str[i] == rec) ans = max(ans, 2);
rec = str[i]; c = 1;
}
} else if (str[i] == rec) {
c++;
} else {
ans = max(ans, c);
rec = str[i]; c = 1;
}
}
return max(ans, c);
}
int main() {
int cas;
scanf("%d", &cas);
for (int i = 1; i <= cas; i++) {
scanf("%s", str);
printf("Case %d: %d\n", i , solve());
}
return 0;
}