蓝桥杯练习系统(算法训练)ALGO-1004 无聊的逗

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

  逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中。不过他想到了一个游戏来使他更无聊。他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。

输入格式

  第一行一个数n,表示n个棍子。第二行n个数,每个数表示一根棍子的长度。

输出格式

  一个数,最大的长度。

样例输入

4
1 2 3 1

样例输出

3

数据规模和约定

  n<=15

#include<iostream>
using namespace std;
const int N=15;
int b[1<<N];//若有N个木棍,则有2^N种取法(每个木棍取或不取两种情况) 
int main(){
	int n;
	scanf("%d",&n);
	int a[n];
	for(int i=n-1;i>=0;i--){
		scanf("%d",&a[i]);
	}
	for(int i=0;i<(1<<n);i++){//共2^n种取法 
		for(int j=0;j<n;j++){//遍历看看取到的木棍,将取到的木棍长度相加 
			if(i&(1<<j)){
				b[i]+=a[j];
			}
		}
	}
	int ans=0; 
	for(int i=0;i<(1<<n);i++){
		for(int j=0;j<(1<<n);j++){
			if(!(i&j)&&b[i]==b[j]){//若两种取法没有取到同一个木棍,且两取法得到的木棍总和相等,则得出一个答案 
				ans=max(ans,b[i]);
			}
		}
	} 
	printf("%d\n",ans);
	return 0;
} 

思路:从n个木棍中选木棍,共有2^{n}种选法(每个木棍选或不选),这2^{n}种方法中如果有两种方法没有取到相同的木棍(木棍可以不用全部被取完,只要两种取到的木棍不重合即可),且总长度相等,则为一种答案。最终的答案只是为总长度最大的,用max函数比较一下即可。

若木棍长度数组:1 2 3 1,b[j]表示第j+1种取法,用0表示不取,1表示取。

例:b[1]:0 0 0 1 指的是第2种方法只取了最后的木棍

       b[15]:1 1 1 1 指的是第16种取法四个木棍全取

可以用二进制表示这2^4种取法:0000、0001、0010、0011、……、1111,每一种取法通过和0001(判断是不是取第4个)、0010(判断是不是取第3个)、0100、1000按位与得知是否取了第几个木棍。

代码中倒序输入为的就是按位与时判断第几个木棍:

for(int j=0;j<n;j++){//遍历看看取到的木棍,将取到的木棍长度相加 
			if(i&(1<<j)){
				b[i]+=a[j];
			}
}

因为是加上a[j],例如j=0时,1<<j=0001,a[j]=a[0],而0001表示取到了第4个木棍而不是a[0]第1个木棍,因此要将a数组逆序输入: (0001判断是不是取第4个,取到则加上原数组的第4个,也可以不用逆序输入,把b[i]+=a[j];改为b[i]+=a[n-j-1]即可)

for(int i=n-1;i>=0;i--){
        scanf("%d",&a[i]);
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值