UVa 12545 - Bits Equalizer(贪心)

给出两个01?串,求通过多少次变换可以让第一个与第二个相同。可进行的变换有把0变成1,把?变成0或1,交换两个字符。

使用交换把两串相同的交换没有意义,所以仅对两串有差异的地方进行统计。0可以任意变成1,而0只能通过交换或?产生,所以对第一个串中需要由1变为0的处理就成了关
键。首先是用效率最高的交换,然后使用?,如果交换和使用?都无法满足,那么就不能相同。处理完需要由1变为0的之后的就简单了,每处不同最少需要进行一次操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=210;
char s[maxn],s0[maxn];
int solve(int n){
int sum,_0_1,_1_0,_1_q,_0_q,cnt;
sum=_1_0=_0_1=_1_q=_0_q=cnt=0;
for(int i=0;i<n;++i){
if(s0[i]=='1'&&s[i]=='?') ++sum,++_1_q;
if(s0[i]=='0'&&s[i]=='?') ++sum,++_0_q;
if(s0[i]=='1'&&s[i]=='0') ++sum,++_1_0;
if(s0[i]=='0'&&s[i]=='1') ++sum,++_0_1;
}
int t=min(_1_0,_0_1);//交换。
cnt+=t,_0_1-=t,sum-=2*t;
t=min(_1_q,_0_1);//使用?替换后交换。
cnt+=2*t,_0_1-=t,sum-=2*t;
if(_0_1) return -1;
return cnt+sum;
}
int main(){
int t,tt=0;
scanf("%d",&t);
while(t--){
scanf("%s%s",s,s0);
printf("Case %d: %d\n",++tt,solve((int)strlen(s0)));
}
return 0;
}

本文迁移自我的 CSDN博客 ,格式可能有所偏差。