リンク
[ https://codeforces.com/problemset/problem/1138/B ]
問題の意味
あなたが同時にテイクで、文字列の半分を選ぶことができれば、二つの文字列0,1を与えます。
現在の数が1に等しくなるように第1列は、数が残りの第2列1から選択されていません。
分析
私は長い時間のような結果が、それは動作しません分類を議論してきたので、まず第一に、私は、本当に愚かでした。
だから、今回はデータを見てn個のn * nのである<= 5000は、解決することができます。どのように暴力?
この問題は、あなたの中学校の具現化の数学的なスキルです。統計00,01,10,11、B、C、Dの数、
我々は数00、A、B、C、Dから選択されることを前提とし、
A + B + C + D = N / 2、A + B + C + D = N;
我々は列挙し、次に質問の意味を満たすために必要
これは本当にああ、数学の問題ですが、またミスをより安定させることは容易ではありませんので、私の反応は複雑さに敏感ではない、時には、それは、暴力暴力的になることができます。
私はまだ料理を捉え、分析、の複雑さ。
コード
#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;
}