蓝桥杯 算法训练 无聊的逗
题目描述
- 资源限制
时间限制:1.0s 内存限制:256.0MB - 问题描述
逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中。不过他想到了一个游戏来使他更无聊。他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。 - 输入格式
第一行一个数n,表示n个棍子。第二行n个数,每个数表示一根棍子的长度。 - 输出格式
一个数,最大的长度。 - 样例输入
4
1 2 3 1 - 样例输出
3 - 数据规模和约定
n<=15
方案1 递归搜索 (存在左右两边重复搜索的情况)
#include<iostream>
#include<cmath>
using namespace std;
int n; //n个棍子
int stick[15]; //每个棍子的长度
int MAX; //满足题意所能拼成的最大长度
int sum; //所有棍子的总长度
//函数参数:假设分左右两边,左边棍子总长度L,右边棍子总长度R,棍子数组stick,棍子总数n,剩余棍子总长度rest,当前棍子索引cur
//函数功能:在保证左右两边棍子相等的条件下,使左右两边棍子尽可能长
void f(int L, int R, int stick[], int n, int rest, int cur){
//当两边棍子之差大于剩余棍子总长度时,不可能满足左右两边棍子相等,结束递归
if(abs(L-R)>rest){
return ;
}
//当两边棍子长度相等时,更新最大长度
if(L==R && MAX<L){
MAX = L;
}
//当两边棍子长度不相等时,当前棍子有三种放置方法:
for(int i=cur; i<n; i++){
//1.当前棍子放在左边
f(L+stick[i], R, stick, n, rest-stick[i], cur+1);
//2.当前棍子放在右边
f(L, R+stick[i], stick, n, rest-stick[i], cur+1);
//3.当前棍子舍弃
cur++;
}
}
int main(){
cin>>n;
for(int i=0; i<n; i++){
cin>>stick[i];
sum += stick[i];
}
f(0, 0, stick, n, sum, 0);
cout<<MAX<<endl;
return 0;
}
方案2 数学公式(参考网上题解)
#include<iostream>
#include<algorithm>
using namespace std;
int n; //n个棍子
int stick[15]; //每个棍子的长度
int MAX; //满足题意所能拼成的最大长度
int sum; //所有棍子的总长度
int main(){
cin>>n;
for(int i=0; i<n; i++){
cin>>stick[i];
sum += stick[i];
}
sum /= 2;
sort(stick, stick+n);
// 关键思想(我没证出来,但确实对了)
for(int i=n-1;i>=0;i--){
if(sum-MAX >= stick[i]){ //比较得出最大长度
MAX += stick[i];
}
}
cout<<MAX<<endl;
return 0;
}
版权声明:本文为weixin_45728231原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。