P1-2017级第一次算法上机 E 比特手链

时间:2021-12-02 16:40:45

题目描述

  叶姐要想哥赠送一串比特手链,这个手链由01组成。想哥买了手链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;

思路

  碰到这种类型,一般都要先手动模拟,寻找规律。

  通过手动计算可以发现,若a[i] == a[j],则三个运算均不会造成影响;只有a[i] != a[j]时,即一个为0一个为1,才会造成改变。

  对于&:相当与把1变成0;对于|:相当于把0变成1;对于^,相当于交换。

  所以,如果原串全为0或全为1,由于A!=B,所以是无解的;否则解的个数即为max(0变成1的数量,1变成0的数量),也就是说,尽量使用^交换一次性解决两个,无法交换了再用&或|一次修改一个。

参考代码

 1 //我的版本
 2 #include<stdio.h>
 3 #include<string.h>
 4 #define MAXN 1000002
 5 int main()
 6 {
 7     int T;//数据组数
 8     scanf("%d",&T);
 9     while(T--){
10         char b[MAXN],a[MAXN];
11         scanf("%s%s",b,a);
12         int i,ans_b0 = 0;
13         int len = strlen(b);
14         int t01 = 0,t10 = 0;
15         for(i = 0;i < len;i++){
16             if(b[i] == '0')
17                 ans_b0++;
18             if(b[i] == '0' && a[i] == '1')
19                 t01++;
20             if(b[i] == '1' && a[i] == '0')
21                 t10++;
22         }
23         if(ans_b0 == len || ans_b0 == 0){
24             printf("-1\n");
25             continue;
26         }
27         printf("%d\n",Max(t01,t10));
28     }
29 
30     return 0;
31 }
32 
33 int Max(int a,int b)
34 {
35     return a > b ? a : b;
36 }

 

 1 //助教的版本
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 const int N=1000010;
 7 int len,l,r,t,sum;
 8 char a[N],b[N];
 9 
10 inline int max(int a,int b) {
11     return a>b?a:b;
12 }
13 
14 int main() {
15     for(scanf("%d",&t);t--;l=r=sum=0) {
16         scanf("%s%s",a,b);
17         len=std::strlen(a);
18         for(int i=0;i<len;++i) sum+=a[i]-'0';
19         if(sum==0 || sum==len) {
20             puts("-1");
21             continue;
22         }
23         for(int i=0;i<len;++i)
24         if(a[i]!=b[i])
25             a[i]=='0' ? ++l : ++r;
26         printf("%d\n",max(l,r));
27     }
28     return 0;
29 }