2017级北航算法软院第一次算法上机--比特手链

关于北航OJ的个人GitHub地址






时间限制:1000ms 内存限制:65536kb OJ编号:1413

通过率:14/28 (50.00%) 正确率:14/79 (17.72%)

题目描述
叶姐要想哥赠送一串比特手链,这个手链由0和1组成。想哥买了手链B,无意间得知叶姐想要同样长度的手链A。想哥囊中羞涩,只能手工调整手链。他希望最少通过以下操作进行最少步骤把B变成A。注意:A != B

对于一个串S:
操作1——选择下标i,j,i != j:
·result = S[i] & S[j]
·S[i] = result & S[i]
·S[j] = result & S[j]

操作2——选择下标i,j,i != j:
·result = S[i] | S[j]
·S[i] = result | S[i]
·S[j] = result | S[j]

操作3——选择下标i,j,i != j:
·result = S[i] ^ S[j]
·S[i] = result ^ S[i]
·S[j] = result ^ S[j]

问想哥最少多少步能达成心愿。如果想哥无法达成心愿,输出-1。
输入
第一个数为数据组数T

接下来2T行,第2i - 1行为手链B,第2i行为手链A

输出
对于每组数据,输出一行,最少的步骤数。特别地,如果无法达成,输出-1。

输入样例
2
101
010
1111
1010
输出样例
2
-1
Hint
T<=5;
长度<=10^6;



AC代码(C++):

#include <cstdio>
#include <string>
#include <iostream>

using  namespace std;

int T;
string A,B;

int main()
{
    for(scanf("%d",&T);T--;){
        cin>>B>>A;
        int len=A.size();
        int cnt1=0,cnt0=0;
        int b1=0,b0=0;
        for(int i=0;i<len;i++){
            if(A[i]!=B[i]){
                if(B[i]=='0')
                    cnt0++;
                if(B[i]=='1')
                    cnt1++;
            }
            if(B[i]=='0')
                b0++;
            if(B[i]=='1')
                b1++;
        }
        if(b0==len||b1==len){
            printf("-1\n");
            continue;
        }
        if(cnt0==cnt1)
            printf("%d\n",cnt0);
        else{
            int maxcnt=max(cnt0,cnt1);
            printf("%d\n",maxcnt);
        }
    }
}

思路:
   这种题目,思路就是实体化变量。就是把题干里的s[i],s[j]用一个数对来实体化,这道题中就是数对(1,0)。经过实体化后可以发现且运算就是把1变0,把0变0;或运算就是把0变1,把1变1;异或运算就是把1变0,把0变1.这三种运算中异或运算是比较便捷的,因为只需要一次运算就能换两个数,另两个运算只能换1个数。所以要尽快转换,就要多用异或运算。
   具体操作时,就是同时遍历两组字符串,遇上不相同的时候就记录,看B串中不同的是0还是1,cnt1,cnt0分别记录B串异于A串中1和0的个数。如果cnt0= =cnt1,那么把这些1和0用异或运算交换位置即可;若cnt0>cnt1,那么先进行cnt1次异或运算把1变成0,0变成1,然后剩下的cnt0-cnt1个0再用或运算换成1,总的运算次数为cnt0;cnt1>cnt0的情况同理。那么,我们就可以得到一个结论,如果可以实现转换,那么若cnt1!=cnt0,最少的转换次数为max(cnt1,cnt0),其实这个结论在cnt0= =cnt1时也是成立的。
   那么哪种情况是不可以实现转换的呢?答案是若B为全0或者全1的情况下是无法转换的。可以通过分别计算B串中1和0的总个数并将之与B.size()进行比较,若相等则说为全1/0串。






  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值