UVA 12545 Bits Equalizer

本文介绍了一道编程题的解题思路,旨在将一个包含0、1和问号的字符串通过最少的操作步骤转换成另一个只包含0和1的字符串。文章详细解释了解题过程,并提供了一份实现代码。
题目链接: http://www.bnuoj.com/bnuoj/problem_show.php?pid=27865

Bits Equalizer

1000ms
131072KB
 
This problem will be judged on UVA. Original ID:  12545
64-bit integer IO format:  %lld      Java class name:  Main
Font Size:   
Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  • [PDF Link]

    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 convertS 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
    

     

    Source

     
    题目大意:将第一个字符与第二个字符每一个位置都相对应,至少需要移动的次数为多少。有以下的规则:1、0可以变成1;2、?可以变成0 or 1;3、任意0与1的位置可以互换
     
    解题思路:统一0和1以及?的个数,因为?一定要变换,所以最少移动次数也得有?个数次,所以在其基础上加就可以了。
    分两种情况考虑:(交换、变换)
    优先变换情况:
    1、存在1/0,并且后面可以找到0/1,那么交换。
    2、存在1/0,但是找不到与其对应的0/1可以交换,那么就只能选择?/1,那么交换。
    变换情况:
    1、存在0/1,这种情况的话就直接把0变换成1即可。
     
    综上,只要把所有情况考虑到,AC就不再是梦想啦,哇哈哈~~
     
    详见代码。
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 int main ()
     8 {
     9     int n,len1,flag=1;
    10     char s[110],t[110];
    11     scanf("%d",&n);
    12     while (n--)
    13     {
    14         scanf("%s%s",s,t);
    15         len1=strlen(s);
    16         //len2=strlen(t);
    17         int a,b,c,aa,bb;
    18         a=b=c=aa=bb=0;
    19         for (int i=0; i<len1; i++)
    20         {
    21             if (s[i]=='0')
    22                 a++;
    23             else if (s[i]=='1')
    24                 b++;
    25             else
    26                 c++;
    27         }
    28         for (int i=0; i<len1; i++)
    29         {
    30             if (t[i]=='0')
    31                 aa++;
    32             else
    33                 bb++;
    34         }
    35         if (b>bb)
    36         {
    37             printf ("Case %d: -1\n",flag++);
    38             continue;
    39         }
    40         int sum=0;
    41         int j;
    42         if (s[i]=='1'&&t[i]=='0')
    43         {
    44             for (j=0; j<len1; j++)
    45             {
    46                 if (s[j]=='0'&&t[j]=='1')
    47                 {
    48                     sum++;
    49                     s[i]='0';
    50                     s[j]='1';
    51                     break;
    52                 }
    53             }
    54             if (j>=len1)
    55                 break;
    56 
    57         }
    58     }
    59     for (int i=0; i<len1; i++)
    60     {
    61         int j;
    62         if (s[i]=='1'&&t[i]=='0')
    63         {
    64             for (j=0; j<len1; j++)
    65             {
    66                 if (s[j]=='?'&&t[j]=='1')
    67                 {
    68                     sum++;
    69                     s[i]='?';
    70                     s[j]='1';
    71                     break;
    72                 }
    73             }
    74             if (j>=len1)
    75                 break;
    76         }
    77     }
    78     for (int i=0; i<len1; i++)
    79     {
    80         if (s[i]=='0'&&t[i]=='1')
    81             sum++;
    82         //ans=sum+c;
    83     }
    84     printf ("Case %d: %d\n",flag++,sum+c);
    85 }
    86 return 0;
    87 }

     

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值