进阶89-分糖果

肖恩和帕特里克是兄弟,他们从他们的父母那里得到了很多糖果。每一块糖具有一个正整数的价值,孩子们希望分他们得到的糖果。首先,肖恩将这些糖果分成两堆,并选择一堆给帕特里克。然后,帕特里克将尝试计算每堆的价值,其中每堆的价值是那堆糖果价值的总和,如果他觉得没有平等的价值,他将开始哭了起来。
不幸的是,帕特里克太小了,所以不能正确的计算。他只会二进制无进位的加法。比如说,他想算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
肖恩数学很好,他想得到价值总和更高的糖果并且不让他的弟弟哭。如果可能,他会分成两个非空的糖果袋,让帕特里克认为,双方都有相同的值的糖果。给你每一袋糖果每一块糖果的价值,我们想知道是否可能让帕特里克相信他们得到糖果价值的总量是相同的。如果可能计算出肖恩能得到的最大的价值。

输入

2
5 1 2 4 5 8
3 3 5 6

输出

NO
11

开始是想的是二进制转换再相加输出,在通过dp来找到所以可能。就写了个。后来再网上搜到了个是使用异或来写的,这个是知道的,也就以前学的时候用了下,后来。。

自己写的

#include <iostream>
#include <cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
//得到a,b使用二进位不进制相加得到的结果
int GetV(int a,int b){
	int A[10],B[10],C[10];
	int lenA=0,lenB=0;
	int i,t,sum;
	//二进制
	while(a){
		A[lenA++]=a%2;
		a=a/2;
	}
	while(b){
		B[lenB++]=b%2;
		b=b/2;
	}
	i=0;
	while(lenA<lenB)A[lenA++]=0;
	while(lenB<lenA)B[lenB++]=0;
	while(i<lenA){
		C[i]=(A[i]+B[i])%2;
		i++;
	}
	t=1;
	sum=0;
	for(i=0;i<lenA;i++){
		sum=sum+t*C[i];
		t=t*2;
	}
	return sum;
}

int main(){
	vector<int> dp;
	int n[10000];
	int N,T,i,j,t,allvalue;
	int A[20];
	int max,lenN;
	while(scanf("%d",&T)!=EOF){
		while(T--){
			scanf("%d",&N);
			allvalue=0;
			for(i=0;i<N;i++){
				scanf("%d",&A[i]);
				allvalue=allvalue+A[i];
			}
			t=0;
			//二进位制和
			dp.push_back(A[0]);
			//十进制加和
			n[t++]=A[0];
			for(i=1;i<N;i++){
				lenN = dp.size();
				dp.push_back(A[i]);
				n[t++]=A[i];
				for(j=0;j<lenN;j++){
					dp.push_back(GetV(dp[j],A[i]));
					n[t++]=n[j]+A[i];
				}
			}
			max=-1;
			t=0;
			for(vector<int>::iterator it = dp.begin(); it != dp.end()-1; it++){
				if(*it == allvalue-n[t]){
					if(max<n[t])max=n[t];
				}
				t++;
			}
			dp.clear();
			
			if(max<=(allvalue+1)/2 || max==-1)printf("NO\n");
			else printf("%d\n",max);
		}
	}
	return 0;
}

使用异或求解:

#include <stdio.h>
int main(){
	int T,n,temp,sum,min,account;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		scanf("%d",&temp);
		sum=temp;
		min=temp;
		account=temp;
		n--;
		while(n--){
			scanf("%d",&temp);
			sum=sum^temp;
			account+=temp;
			if(temp<min)min=temp;
		}
		if(sum)printf("NO\n");
		else printf("%d\n",account-min);
	}
	return 0;	
} 

异或求解来源
https://blog.csdn.net/qq_38344326/article/details/104481308

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值