UVA 12545 Bits Equalizer(模拟+贪心)

B - Bits Equalizer
Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

Download as PDF

You are given two non-empty strings S and T of equal lengths. S contains the characters `0', `1' and `?', whereas T contains `0' and `1' only. Your task is to convert S into T in minimum number of moves. In each move, you can

  1. change a `0' in S to `1'
  2. change a `?' in S to `0' or `1'
  3. swap any two characters in S

As an example, suppose S = "01??00" and T = "001010". We can transform S into T in 3 moves:

  • Initially S = "01??00"
  • - Move 1: change S[2] to `1'. S becomes "011?00"
  • - Move 2: change S[3] to `0'. S becomes "011000"
  • - Move 3: swap S[1] with S[4]S becomes "001010"
  • S is now equal to T

Input 

The first line of input is an integer C (C$ \le$200) that indicates the number of test cases. Each case consists of two lines. The first line is the string S consisting of `0', `1' and `?'. The second line is the string T consisting of `0' and `1'. The lengths of the strings won't be larger than 100.

Output 

For each case, output the case number first followed by the minimum number of moves required to convert S into T. If the transition is impossible,output `-1' instead.

Sample Input 

3
01??00
001010
01
10
110001
000000

Sample Output 

Case 1: 3
Case 2: 1
Case 3: -1

刚开始看题目以为是编辑距离(DP),后来分析样例发现其实不是相邻的两个交换,任意位置都可以交换

定义:one zero表示原串的0和1的个数 one1和zero1表示目的串的0和1的个数

分三种情况:

1、原串的0的个数和?个数和小于目的串0个数,一定输出-1

2、原串0多于目的串,那么先用?变换成1,选取对应目的串也是1的位置先变,如果不够再将其他?变成1,如果还不够找目的串相对位置为1的0变成1.......

3、原串1个数少于目的串,那么说明原串0,多了,先把1补全,然后其他的?换成0,用的也是贪心的思路,和上面情况2类似

总之能用?的要用?


#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
#define maxn 500
char begin[maxn],end[maxn];
int zero,one,zero1,one1;
int main(){
    int i,j,k,t,len,ans,now,cas=0;
    scanf("%d",&t);
    while(t--){
        scanf("%s%s",begin,end);
        printf("Case %d: ",++cas);
        zero=one=zero1=one1=0;
        ans=0;
        len=strlen(begin);
        for(i=0;i<len;i++){
            if(begin[i]=='0')zero++;
            else if(begin[i]=='1')one++;
            if(end[i]=='0')zero1++;
            else if(end[i]=='1')one1++;
        }
        if(len-one<zero1){//case 1
            printf("-1\n");
            continue;
        }
        if(zero<=zero1){//case 2 zero can only change by '?'
            k=zero1-zero;
            for(i=0;i<len&&k>0;i++){
                if(begin[i]=='?'&&end[i]=='0')
                    begin[i]='0',ans++,k--;
            }
            for(i=0;i<len && k>0;i++)
                if(begin[i]=='?')begin[i]='0',ans++,k--;
            for(i;i<len;i++)if(begin[i]=='?') begin[i]='1',ans++;
            now=0;
            for(i=0;i<len;i++)
                if(begin[i]!=end[i])now++;
            ans+=now/2;
            printf("%d\n",ans);
            continue;
        }
        if(one<=one1){
            k=one1-one;
            for(i=0;i<len&&k>0;i++)if(begin[i]=='?'&&end[i]=='1')begin[i]='1',ans++,k--;
            if(k>0){
                for(i=0;i<len&&k>0;i++)if(begin[i]=='?')begin[i]='1',ans++,k--;
                if(k>0){
                    for(i=0;i<len&&k>0;i++)if(begin[i]=='0'&&end[i]=='1')begin[i]='1',ans++,k--;
                    for(i=0;i<len&&k>0;i++)if(begin[i]=='0'&&end[i]!='0')begin[i]='1',ans++,k--;
                    for(i=0;i<len&&k>0;i++)if(begin[i]=='0')begin[i]='1',ans++,k--;
                }
            }
            for(i=0;i<len;i++)if(begin[i]=='?') begin[i]='0';
            now=0;
            for(i=0;i<len;i++)if(begin[i]!=end[i])now++;
            ans+=now/2;
            printf("%d\n",ans);
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值