https://codeforces.com/contest/1535/problem/C
做法有点像一道叫最大上升子序列的题(?)
过程有点啰嗦了,建议直接看代码体会
input
3
0?10
???
?10??1100
output
8
6
25
题意:
给T,给T组由 0,1,? 构成的字符串,“?”可以变成 0&1
求最大每组相邻两个数不相等的串的个数,称为Unstable串
如:10101中符合条件的有:1、0、1、0、1、10、01、10、01、101、010、101、1010、0101、10101一共15个
做法:(假定字符串为s[],并且答案输出为res)
首先设定一个start,从头向后搜索,会出现一下几种情况
1.01010
我们把起点设在s[0],经过到s[4]时候都是成立的,所以让res += i - start + 1
以下打表验证正确性
/*
s[] res (start = 0) res += i - start + 1 || res原来等于1
0-1 1+2
0-2 1+2+3
0-3 1+2+3+4
0-4 1+2+3+4+5
即每录入一个数的时候,会与前面的每个数都组合
01010中
在加入s[3] 时候
会多出s[3] 、 s[2]s[3] 、s[1]s[2]s[3] 、 s[0]s[1]s[2]s[3]四个
*/
2.01?10
如果在搜寻过程中发现是个?,则直接默认成立,进行res +=i-start+1,因为?可以变成0或1
3.?01
如果开头就是?,则默认第二个直接成立。
(具体操作在代码中看,难以用语言表达)
4.
01???10
01???01
01????10
01????01
判断中间问号数量的和两端是否相等的成立条件
直接说不成立的判断结论:
一:两端不相等且中间有奇数个 ?
二;两端相等且中间有偶数个 ?
AC代码(看dalao的)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
string s;
cin >> s;
ll len = s.size();
ll start = 0;
ll idx = 0;
if (s[0] == '?')
idx = -1;
ll res = 1;
for (ll i = 1; i < len; i++)
{
if (s[i] != '?')
{
if (idx != -1)
{
if (s[idx] == s[i] && (i - idx - 1) % 2 == 0 || s[idx] != s[i] && (i - idx - 1) % 2 == 1)
{
start = idx + 1;
}
}
idx = i;
}
res += i - start + 1;
}
cout << res << "\n";
}
return 0;
}
有问题请指正,虚心受教