UVA 12545 Bits Equalizer(模拟+贪心)

来源:互联网 发布:keynote windows能用吗 编辑:程序博客网 时间:2024/04/29 12:19

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

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 

301??000010100110110001000000

Sample Output 

Case 1: 3Case 2: 1Case 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 500char 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;}




原创粉丝点击