C. Balanced Bitstring(字符串+思维) Codeforces Round #668 (Div. 2)

原题链接: https://codeforces.com/contest/1405/problems

C. Balanced Bitstring(字符串+思维) Codeforces Round #668 (Div. 2)_第1张图片
测试样例

input
9
6 4
100110
3 2
1?1
3 2
1?0
4 4
???
7 4
1?0??1?
10 10
11??11??11
4 2
1??1
4 4
?0?0
6 2
???00
output
YES
YES
NO
YES
YES
NO
NO
YES
NO

Note

For the first test case, the string is already a 4-balanced bitstring.
For the second test case, the string can be transformed into 101.
For the fourth test case, the string can be transformed into 0110.
For the fifth test case, the string can be transformed into 1100110.

题意: 给你一个字符串长度,字符串和子串的长度,其中字符串中的 ? ? 可以代替0或1,(注意:确定代替之后就不能更改了)请你判断该字符串的 k k k长度的子串中的0和1数量是不是相等的。

解题思路: 这个题目出的很好,昨天没有写出来,今天补的题解。对于这个题目,我们是要将所有的子字符串关联起来的,不能孤立开来。对于第一个子字符串是从 s 0 − > s k − 1 s_0->s_{k-1} s0>sk1,而第二个子字符串即是 s 1 − > s k s_1->s_k s1>sk,我们发现了什么?第二个子字符串比第一个少了 a 0 a_0 a0多了 a k a_k ak 如果第一个子字符串是满足的,那么第二个满足的条件是不是 a 0 = = a k a_0==a_k a0==ak,我们知道这个有什么用呢?这样推下去,第 i i i个子字符串和第 i % k i\%k i%k这个子字符串是要相同的。这样如果第一个字符串串满足相等条件且我们的子字符串都满足这个递推规则,那么所有的子字符串自然都是满足的。OK,我们具体看代码。

AC代码

/*
*邮箱:[email protected]
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int t,n,k;
string s;
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>t){
		while(t--){
			cin>>n>>k;
			cin>>s;
			bool flag=true;
			rep(i,k,n-1){
				//由于是对于所有的子字符串都应有相等的0或1,而从第一个子字符串开始就是减少开头一个,增加后面一个,如果这两个字符是相同的,自然无需考虑
				if(s[i]=='?'||s[i]==s[i%k])//这两种情况都是已经满足的。
					continue;
				if(s[i%k]=='?')
					s[i%k]=s[i];
				else{
					flag=false;//说明出现不等,不能成立。
					break;
				}
			}
			//接下来要对第一个子字符串进行检验,因为我们是根据这个来的。
			int cnt0=0,cnt1=0;
			rep(i,0,k-1){
				if(s[i]=='0')
					cnt0++;
				if(s[i]=='1')
					cnt1++;
			}
			if(cnt0>k/2||cnt1>k/2)//这种情况说明不符合了。
				flag=false;
			if(flag)
				cout<<"YES"<<endl;
			else
				cout<<"NO"<<endl;
		}
	}
	return 0;
}

你可能感兴趣的:(#,CF,思维,字符串,字符串)