1. 程式人生 > >P1-2017級第一次演算法上機 E 位元手鍊

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\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 }