uva12545 比特变换器(贪心)

uva12545 比特变换器(贪心)

输入两个等长的串S,T(长度小于100),其中S包含字符0,1,?,T中包含0和1。有三种操作:将S中的0变为1,?变为0或1,交换S中的任意两个字符。求将S变成T的最少步数。

首先考虑去掉问号。设S中1的个数为one1,T中1的个数为one2。在one1<one2的前提下,肯定是把问号填成与T中相同的数字更优。如果one1=one2,那么问号中只能填0。接着就是考虑将0变成1,相同的思路即可。最后等到one1=one2,统计S和T中不同的数字,计算出还要再走几步即可。

#include <cstdio>
#include <cstring>
using namespace std;

const int maxl=105;
int T, l1, l2, one1, one2, step;
char s1[maxl], s2[maxl];

int main(){
    scanf("%d", &T);
    for (int it=1; it<=T; ++it){
        scanf("%s%s", s1, s2);
        one1=one2=step=0; int tmp=0;
        l1=strlen(s1); l2=strlen(s2);
        for (int i=0; i<l1; ++i)
            if (s1[i]=='1') ++one1;
        for (int i=0; i<l2; ++i)
            if (s2[i]=='1') ++one2;
        if (l1!=l2||one1>one2){
            printf("Case %d: -1\n", it);
            continue; }
        for (int i=0; i<l1; ++i)
            if (s1[i]=='?'){  //用贪心法去除所有问号
                s1[i]=s2[i];
                if (s1[i]=='1') ++one1;
                if (one1>one2) --one1, s1[i]='0';\
                ++step;
            }
        for (int i=0; i<l1; ++i) //用贪心法化0为1
        if (one1<one2&&s1[i]=='0'&&s2[i]=='1'){
            ++one1; s1[i]='1'; ++step;
        }
        for (int i=0; i<l1; ++i) //统计不同之处
            if (s1[i]!=s2[i]) ++tmp;
        step+=tmp/2; //这是由于只有0和1
        printf("Case %d: %d\n", it, step);
    }
    return 0;
}
posted @ 2018-02-19 17:57  pechpo  阅读(169)  评论(0编辑  收藏  举报