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

127 篇文章 3 订阅
20 篇文章 0 订阅

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

在这里插入图片描述
测试样例

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代码

/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//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;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

unique_pursuit

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值