zoukankan      html  css  js  c++  java
  • P1-2017级第一次算法上机 E 比特手链

    题目描述

      叶姐要想哥赠送一串比特手链,这个手链由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
    ");
    25             continue;
    26         }
    27         printf("%d
    ",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
    ",max(l,r));
    27     }
    28     return 0;
    29 }
  • 相关阅读:
    SQL列类型
    垂直显示查询结果
    在mysql中如何写注释语句
    离开Autodesk,开启新篇章
    Autodesk 为其云技术发布新品牌- Autodesk Forge
    Using View and Data API with Meteor
    View and Data API Tips: Constrain Viewer Within a div Container
    View and Data API Tips: Hide elements in viewer completely
    View and Data API Tips : Conversion between DbId and node
    使用AxisHelper帮助理解View and Data API中的坐标系统
  • 原文地址:https://www.cnblogs.com/zjsyzmx0527/p/10164483.html
Copyright © 2011-2022 走看看