codeforces Round #668 (Div. 2) 1405C Balanced Bitstring

题目链接

在这里插入图片描述

题目翻译:

一个bitstring是一个只包含字符’0’和’1’的字符串。如果一个bitstring的每个长度为k的子字符串拥有相同数量的’0’和’1’(数量各为k/2),则称其为k-balanced
给你一个整数k和一个只由字符’0’,‘1’和’?‘组成的字符串s。你需要判断是否可以通过将’?‘替换成’0’或’1’,使其变成k-balanced
通过删除字符串b的前几个字符和后几个字符,使得字符串b变为字符串a,则称a是b的子字符串。

解题思路:

在这里插入图片描述
比如这个例子,方框里的数字代表子字符串,我们可以发现移出框的数字和移入框的数字一定要相等。进一步就可以发现所有下标对k取余相等的位置的数一定要相等。
在这里插入图片描述
这样我们可以先判断是否所有下标对k取余相等的位置的数都可能相等,如果有可能相等,再判断一下k个数中是否1的数量和0的数量都小于等于k/2,因为下标对k取余相等的位置的数都相等,所以我们只需要判断前k个数就行了。

代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
int t,n,k;
string s;
int main(){
    
    
//	freopen("1.txt","r",stdin);
	cin>>t;
	while(t--){
    
    
		cin>>n>>k;
		getline(cin,s);
		cin>>s;
		int flag=0;
		int tmp,s0=0,s1=0;
		for(int i=0;i<k;i++){
    
    
			if(s[i]=='?') tmp=-1;
			else tmp=s[i]-'0';
			for(int j=i+k;j<n;j+=k){
    
    
				if(s[j]=='?'){
    
    
					if(tmp!=-1) s[j]='0'+tmp;
				}else{
    
    
					if(tmp!=-1){
    
    
						if(s[j]-'0'!=tmp){
    
    
							flag=1;
							break;
						}
					}else{
    
    
						tmp=s[j]-'0';
					}
				}
			}
			if(flag==1){
    
    
				break;
			}
			if(tmp!=-1){
    
    
				tmp==0?s0++:s1++;
			}
		}
		if(s0>k/2||s1>k/2) flag=1;
		cout<<(flag?"NO":"YES")<<endl;
	}
	return 0;
}
我的代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
    
    
//	freopen("1.txt","r",stdin);
	int t,n,k;
	string s;
	cin>>t;
	while(t--) {
    
    
		cin>>n>>k;
		getline(cin,s);
		cin>>s;
		int s1=0,s2=0;
		for(int i=0; i<k; i++) {
    
    
			if(s[i]=='0') s1++;
			else if(s[i]=='1') s2++;
			else {
    
    
				if(s1==k/2) {
    
    
					s[i]='1';
					s2++;
				} else if(s2==k/2) {
    
    
					s[i]='0';
					s1++;
				}
			}
		}
		if(s1>k/2||s2>k/2) {
    
    
			cout<<"NO"<<endl;
			continue;
		}
		int l=0,r=k,flag=0;
		for(int i=k; i<n; i++) {
    
    
			if(s[l]!=s[r]&&s[l]!='?'&&s[r]!='?') {
    
    
				flag=1;
				break;
			} else if(s[l]=='?') {
    
    
				if(s[r]=='0') s1++;
				else if(s[r]=='1') s2++;
			} else if(s[r]=='?') {
    
    
				if(s[l]=='0') s[r]='0';
				else if(s[l]=='1') s[r]='1';
			}
			if(s1>k/2||s2>k/2) {
    
    
				flag=1;
				break;
			}
			if(s1==k/2) {
    
    
				for(int j=l; j<r; j++) {
    
    
					if(s[j]=='?') s[j]='1';
				}
			} else if(s2==k/2) {
    
    
				for(int j=l; j<r; j++) {
    
    
					if(s[j]=='?') s[j]='0';
				}
			}
			l++,r++;
		}
		if(flag==0) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}
总结:

找规律,多动脑才能敲出简洁的代码。

猜你喜欢

转载自blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/108463584
今日推荐