Solution
我感觉这题比这场的CD难多了(E以后没时间看,但99%是做不出的)
刚开始想过
d
p
dp
dp,但发现要保存前
i
i
i个数,
0
0
0和
1
1
1的个数差,还有
s
1
s1
s1中选择的长度,会爆
然后想到了模拟,枚举两个串中
1
1
1的个数
k
k
k
对于每个
i
i
i,
s
1
s1
s1和
s
2
s2
s2的情况只有
4
4
4种:
1
:
s
1
[
i
]
=
′
0
′
,
s
2
[
i
]
=
′
0
′
1:s1[i]='0',s2[i]='0'
1:s1[i]=′0′,s2[i]=′0′
2
:
s
1
[
i
]
=
′
0
′
,
s
2
[
i
]
=
′
1
′
2:s1[i]='0',s2[i]='1'
2:s1[i]=′0′,s2[i]=′1′
3
:
s
1
[
i
]
=
′
1
′
,
s
2
[
i
]
=
′
0
′
3:s1[i]='1',s2[i]='0'
3:s1[i]=′1′,s2[i]=′0′
4
:
s
1
[
i
]
=
′
1
′
,
s
2
[
i
]
=
′
1
′
4:s1[i]='1',s2[i]='1'
4:s1[i]=′1′,s2[i]=′1′
用
a
a
a数组来记录
s
1
s1
s1中选择的点,
b
b
b来记录
s
2
s2
s2中选择的点
a
[
1..
k
]
a[1..k]
a[1..k]装的都是
s
1
[
i
]
=
′
1
′
s1[i]='1'
s1[i]=′1′的点,
a
[
k
+
1..
n
/
2
]
a[k+1..n/2]
a[k+1..n/2]装的都是
s
1
[
i
]
=
′
0
′
s1[i]='0'
s1[i]=′0′的点,
b
[
]
b[]
b[]同理
然后
a
a
a中尽可能选
3
3
3,
b
b
b中尽可能选
2
2
2(都得
≤
k
≤k
≤k)
然后
a
,
b
a,b
a,b中不够的用
4
4
4补
如果用
4
4
4都补不满,那肯定不行
如果
4
4
4有多,那么只能填在
a
,
b
a,b
a,b的
[
1..
k
]
[1..k]
[1..k]部分,尽可能替代
如果
4
4
4还有多,那肯定不定了
a
[
k
+
1..
n
/
2
]
a[k+1..n/2]
a[k+1..n/2]中尽可能填
2
2
2,如果
2
2
2还有多,那肯定也不行了,
因为
2
2
2填在
s
2
s2
s2中就是
1
1
1了,而
s
2
s2
s2的
1
1
1已经满了
剩下的都填
1
1
1,然后输出
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");
}