uva 12545 Bits Equalizer

本文介绍了一个字符串转换问题,任务是将包含‘0’、‘1’和‘?’的字符串S通过最少步骤转化为另一个只包含‘0’和‘1’的字符串T。文章详细解释了解决方案,并提供了具体的例子和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ofmoves. 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 ”001010SisnowequaltoT

Input

The first line of input is an integer C (C 200) that indicates the number of test cases. Each caseconsists of two lines. The first line is the string S consisting of ‘0’, ‘1’ and ‘?’. The second line is thestring 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 toconvert 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
//
//  main.cpp
//  uva 12545 - Bits Equalizer
//
//  Created by XD on 15/8/16.
//  Copyright (c) 2015年 XD. All rights reserved.
//



/*
  贪心法
 首先注意到题中所给的变化,只能增加 1 的个数,所以onel1 与onel2的个数是必须相等的
 因此得到了算法的主体
 1 onel1 > onel2     输出-1,因为无论如何变化,第一个串中的1的个数始不会减少
 2 onel1 == onel2    问号全部变成0,然后统计s1和s2不同处有多少个(设为num个),那么ans == 问号的个数 + num/2 。这里的num一定是偶数。很简单,串只是01串,那么某一处不同,则必存在另一处不同。
 3. onel1 < onel2    先变化问号的地方,因为这样肯定不会增加最终的操作次数的。另外处变化成第二个字符串相应的字符(当然如果1的个数已经够了,则后面的问号全部变化为0);接下来如果1的个数还没够,则将串一中的0变化成1,当然也是贪心法,也就是在串一位0串二为1的地方串一0-》1.
 
 
 */
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
char s[110];
char s1[110] ;
int get_ch_num(char s[],int l,char ch )
{
    int num =0  ;
    for (int i = 0; i < l ; i++) {
        if (s[i]==ch) {
            num++ ;
        }
    }
    return num ;
}
int main(int argc, const char * argv[]) {
    int  T ;scanf("%d" ,&T) ;
    int kase = 0;int ans;
    while (T--) {
        ans = 0  ;
        scanf(" %s" ,s)  ;
        scanf(" %s" ,s1) ;
        printf("Case %d: ",++kase) ;
        int len1 = (int)strlen(s) ;
        int len2 = (int ) strlen(s1)  ;
        int onel1 = get_ch_num(s,len1,'1') ;
        int onel2 = get_ch_num(s1 , len2,'1') ;
        if (onel1 > onel2) {
            printf("-1\n")  ;
        }
        else if (onel1 == onel2)
        {
            ans += get_ch_num(s , len1,'?') ;
            int  t =0 ;
            for (int i = 0; i < len1; i++) {
                if (s[i]=='?'   ) {
                    s[i]='0' ;
                }
                if (s[i]!=s1[i]) {
                    t++ ;
                }
            }
            ans+=(t/2) ;
            printf("%d\n",ans) ;
        }
        else{
            int d = onel2 - onel1 ;
            
            for (int i = 0 ; i < len1; i++) {
                if (s[i] =='?') {
                    if (s1[i] == '1'&&d > 0 ) {
                        s[i] = '1' ;ans++ ;
                        d-- ;
                    }
                    else
                    {
                        ans++ ;
                        s[i] = '0' ;
                    }
                }
            }
            if (d>0) {
                for (int i = 0; i < len1; i++) {
                    if (s[i] == '0' && s1[i] == '1'&&d>0) {
                        s[i] = '1' ;d-- ;
                        ans++ ;
                    }
                }
            }
            int  t =0 ;
            for (int i = 0; i < len1; i++) {
                if (s[i]!=s1[i]) {
                    t++ ;
                }
            }
            ans+=(t/2) ;
            printf("%d\n" ,ans) ;
        }
    }
    
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值