Solution
我感觉这题比这场的CD难多了(E以后没时间看,但99%是做不出的)
刚开始想过
,但发现要保存前
个数,
和
的个数差,还有
中选择的长度,会爆
然后想到了模拟,枚举两个串中
的个数
对于每个
,
和
的情况只有
种:
用
数组来记录
中选择的点,
来记录
中选择的点
装的都是
的点,
装的都是
的点,
同理
然后
中尽可能选
,
中尽可能选
(都得
)
然后
中不够的用
补
如果用
都补不满,那肯定不行
如果
有多,那么只能填在
的
部分,尽可能替代
如果
还有多,那肯定不定了
中尽可能填
,如果
还有多,那肯定也不行了,
因为
填在
中就是
了,而
的
已经满了
剩下的都填
,然后输出
Code
有很多冗余的部分,毕竟在打比赛时时间比较紧,一般不会去修改这种东西的
#include<bits/stdc++.h>
using namespace std;
const int N=5002;
int i,j,k,a[N],b[N],t1,t2,t3,t4,c1,c2,c3,c4,n,p1,p2,p3,p4;
char s1[N],s2[N];
vector<int>l1,l2,l3,l4;
int main(){
scanf("%d%s%s",&n,s1+1,s2+1);
for (i=1;i<=n;i++){
if (s1[i]=='0' && s2[i]=='0') c1++,l1.push_back(i);
if (s1[i]=='0' && s2[i]=='1') c2++,l2.push_back(i);
if (s1[i]=='1' && s2[i]=='0') c3++,l3.push_back(i);
if (s1[i]=='1' && s2[i]=='1') c4++,l4.push_back(i);
}
for (k=0;k<=n/2;k++){//要从0开始
t1=c1,t2=c2,t3=c3,t4=c4;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for (i=1;i<=k;i++){
if (t3) t3--,a[i]=3;
else if (t4) t4--,a[i]=4;
if (t2) t2--,b[i]=2;
else if (t4) t4--,b[i]=4;
}
if (k && !a[k] || k && !b[k]) continue;//k=0时不需要判断
for (i=1;i<=k;i++)
if (a[i]==3 && t4) a[i]=4,t4--,t3++;
for (i=1;i<=k;i++)
if (b[i]==2 && t4) b[i]=4,t4--,t2++;
if (t4) continue;
for (i=k+1;i<=n/2;i++)
if (t2) t2--,a[i]=2;
else if (t1) t1--,a[i]=1;
if (!a[n/2] || t2) continue;
for (i=1;i<=n/2;i++){
if (a[i]==1) printf("%d ",l1[p1++]);
if (a[i]==2) printf("%d ",l2[p2++]);
if (a[i]==3) printf("%d ",l3[p3++]);
if (a[i]==4) printf("%d ",l4[p4++]);
}
return 0;
}
puts("-1");
}