B. Circus

链接

[https://codeforces.com/problemset/problem/1138/B]

题意

给你两个字符串0,1那种,你是否可以选出一半的字符串,同时取。
使得当前第一个字符串的1的个数等于,剩下没选的第二个字符串的1的个数。

分析

首先我是真的傻,因为,我一直在哪里分类讨论,结果想了半天,一点都不行。
那么这个时候我们就看数据n<=5000,也就是可以n*n解决。怎么暴力呢?
这题就是你初中的数学功底的体现了。统计00,01,10,11的个数A,B,C,D;
我们假设选的00,01,10,11的个数为a,b,c,d;
a+b+c+d=n/2; A+B+C+D=n;
我们枚举a,那么根据题意需要满足

这题真的就是个数学啊,而且也反应我对复杂度不敏感,有时候可以暴力,就一定暴力,因为它不容易出错比较稳。
复杂度分析,这方面我还是菜了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e3+10;

char s[N],t[N];
int main(){
	int n;
	while(~scanf("%d",&n)){
	
		scanf("%s",s+1);
		scanf("%s",t+1);
		int a,b,c,d,A=0,B=0,D=0,C=0;
		for(int i=1;i<=n;i++)
		if(s[i]=='0'&&t[i]=='1')
		B++;
		else if(s[i]=='1'&&t[i]=='0')
		C++;
		else if(s[i]=='1'&&t[i]=='1')
		D++;
		A=n-(B+D+C);
		//cout<<A<<' '<<B<<' '<<C<<' '<<D<<endl;
		bool flag=0;
		for(a=0;a<=A&&a<=n/2;a++)
		{
			d=B+D+a-n/2;
			if(d>=0&&d<=D&&(a+d)<=n/2){
				for(b=0;b<=B&&(a+b+d)<=n/2;b++){
					c=n/2-(a+b+d);
					if(c>=0&&c<=C){
						flag=1; break;
					}
				}
			}
			if(flag) break;
		}
		if(!flag) puts("-1");
		else {
			//cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
			for(int i=1;i<=n;i++)
			if(s[i]=='0'){
				if(t[i]=='0'&&a){
					printf("%d ",i);
					a--;
				}
				if(t[i]=='1'&&b){
					printf("%d ",i);
					b--;
				}
			}
			else{
				if(t[i]=='0'&&c){
					printf("%d ",i);
					c--;
				}
				if(t[i]=='1'&&d){
					printf("%d ",i);
					d--;
				}
			}
			puts("");
		}
	}
	return 0;
}
posted @ 2019-06-04 16:03  ChunhaoMo  阅读(181)  评论(0编辑  收藏  举报