89 分糖果
作者: xxx時間限制: 10S章節: 一維數組
問題描述 :
肖恩和帕特里克是兄弟,他們從他們的父母那裏得到了很多糖果。每一塊糖具有一個正整數的價值,孩子們希望分他們得到的糖果。首先,肖恩將這些糖果分成兩堆,並選擇一堆給帕特里克。然後,帕特里克將嘗試計算每堆的價值,其中每堆的價值是那堆糖果價值的總和,如果他覺得沒有平等的價值,他將開始哭了起來。
不幸的是,帕特里克太小了,所以不能正確的計算。他只會二進制無進位的加法。比如說,他想算12(二進制爲1100)加5(二進制爲101),他會把最右邊的兩位加法算正確,但是第三位會忘記進位。(即0+0=0,0+1=1,1+0=1,1+1=0)
因此,帕特里克算12加5的結果爲9。下面幾個是帕特里克算的結果:
5 + 4 = 1
7 + 9 = 14
50 + 10 = 56
肖恩數學很好,他想得到價值總和更高的糖果並且不讓他的弟弟哭。如果可能,他會分成兩個非空的糖果袋,讓帕特里克認爲,雙方都有相同的值的糖果。給你每一袋糖果每一塊糖果的價值,我們想知道是否可能讓帕特里克相信他們得到糖果價值的總量是相同的。如果可能計算出肖恩能得到的最大的價值。
輸入說明 :
第一行輸入T(1<T<10),表示接下來輸入T組測試數據。
每組測試數據佔一行,每行包含以下數據,N C1 C2 … Cn(其中N(2 ≤ N ≤ 10)代表從父母那裏得到糖果的總數,C(1 ≤ Ci ≤ 100)代表每塊糖果的價值)
輸出說明 :
若不能輸出NO,若能則輸出肖恩得到的最大的價值。
輸入範例 :
2
5 1 2 4 5 8
3 3 5 6
輸出範例 :
NO
11
+++++++++++++++++++++++++這是分割線++++++++++++++++++++++++
一開始我一點思路也沒有,看了一些大佬的代碼才知道這道題得用異或做(我第一次用異或做題……)
代碼
/*
T89 分糖果
算法概述:這個題的關鍵是“二進制無進位的加法”實際上說的是異或,也就是
二進制中的“同0異1”的操作。
先判斷所有糖果價值的異或(符號爲^)是不是0,
如果是0,那麼肯定能分成“價值”
相等的兩堆(因爲兩個相同二進制數的異或爲0),而如果異或結果爲0,那麼肖恩
能得到的最大的價值的情況一定是“一堆放那個最小价值的,另一堆放除了最小以外的”
因爲如果所有糖果價值的異或爲0,那麼【最小的糖果價值】和【除了最小之外的其他
糖果】的一定是“價值”(也就是二進制)相等的(因爲如果”價值“不等的話所有
糖果的異或不可能是0),所以只需要把最小的那個揪出來把其他的加起來就是肖恩
能得到的最大的價值了
如果是1,那麼不可能分成“價值”相等的兩堆
*/
#include<stdio.h>
#define MAX_SIZE 12
int main() {
int i = 0;
int sum = 0;// 糖果真正價值總和
int min = 105;
int T = 0, N = 0;
int C[MAX_SIZE] = {0};
int xorSum = 0;// 糖果價值的異或和
scanf("%d", &T);
while (T--) {
min = 105, sum = 0;
scanf("%d", &N);
scanf("%d", &C[0]);
sum += C[0];
if (C[0] < min)
min = C[0];
xorSum = C[0];
for (i = 1; i < N; i++) {// 累加糖果價值的異或
scanf("%d", &C[i]);
sum += C[i];
xorSum ^= C[i];
if (C[i] < min)
min = C[i];// 更新最小
}
if (xorSum == 0)// 能分成價值相等的兩堆
printf("%d\n", sum - min);
else
printf("NO\n");
}
return 0;
}
從這道題我學到了:
- 利用異或來解決一些看起來很複雜的問題,比如這裏的兩堆相等