蓝桥杯-算法训练-无聊的逗c++

问题描述

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

输入格式

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

输出格式

  一个数,最大的长度。

样例输入

4
1 2 3 1

样例输出

3

数据规模和约定

  n<=15

 解题思路

        观察这道题,有一种经典的方法是,把每个木棍转化为二进制思想。比如现在有四根木棍,就可以看作有四位二进制数(0000),然后就可以用0、1分别表示没选和选了的小木棍,0110就是第2、第3的小木棍。所以从0000-1111一共16种选小木棍的情况,我们可以把每种情况对应的木棍长度加起来,相当于粘成了第一个大木棍。剩下的就是找上面16种,每个情况对应的补集的子集,这个就是第二个大木棍能粘成长度的情况。还不清楚的可以自己动手在草稿纸上画一画,细心理解。

        举个例子:现在有四个小木棍,对应的长度为 1 2 3 1

        一种情况是选了第2和第4小木棍(1010)粘成第一个大木棍,其补集为0101,就是还剩第1和第3个小木棍,然后补集的子集就是  1、3  小木棍的组合情况,可以只拿  1  (0001)小木棍,也可以只拿  3  (0100)小木棍,最后还可以     1、3  (0101)木棍一起拿,结果就是补集的子集有三种情况0001,0100,0101,这3种情况都可以粘合成第二个大木棍。也就是说,第一个大木棍有16种情况,第二个大木棍的情况则在第一个大木棍情况的补集里,可以在草稿纸上画一画形象理解。

代码解析

        代码中涉及位运算(<<)和与运算(&),这个文档中有关于它们详细的解析。C++ 输出二进制数

代码

#include <iostream>
using namespace std;
int a[15];
int b[1 << 15];  
int main() {
    int n,i,j;
    cin>>n;
    for(i=n-1;i>=0;i--) 
	{  
        cin >> a[i];
    }
   
    for (i=0;i<(1<<n);i++) 
	{  
        for(j=0;j<n;j++) 
		{    						
            if(i&(1<<j))             
                b[i]+=a[j];
        }
    }
    
    int ans=0;
    for (i=0;i<(1<<n);i++) 
	{
        for(j=0;j<(1<<n);j++) 
		{
            if(!(i&j)&&b[i]==b[j]) 
//将这个组合和其它组合进行比较,如果其它组合和这个组合中没有选用相同的木棍,并且这两个组合长度相等,则符合条件,进而与最大长度比较和替换。
			{
                ans=max(ans,b[i]);
            }
        }
    }
    cout<<ans;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值