给定一段一段的绳子,你需要把它们串成一条绳。每次串连的时候,是把两段绳子对折,再如下图所示套接在一起。这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连。每次串连后,原来两段绳子的长度就会减半。
给定 N 段绳子的长度,你需要找出它们能串成的绳子的最大长度。
每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 N (2≤N≤104);第 2 行给出 N 个正整数,即原始绳段的长度,数字间以空格分隔。所有整数都不超过104。
在一行中输出能够串成的绳子的最大长度。结果向下取整,即取为不超过最大长度的最近整数。
8 10 15 12 3 4 13 1 15
14
解题思路
1. 每一次连接的两段绳子,在连接后都会长度减半, 经历过n次连接的一段绳子长度会变为 1/2n , 所以要把尽量短的绳子用于连接, 尽可能减少长度损失
2.基于上面的思路,每次取出两段绳子用于连接, 连接后的长度减半, 而每次连接后产生的新绳子也是一段绳子, 需要计入待连接的绳子中 , 当最后只剩下一段绳子时,所有绳子都串在了一起 跳出循环
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main(){ int n; cin >>n; double temp,b,totalLength{0.0}; vector<double> dArray; for(int i=0;i<n;i++){ cin >> temp; dArray.push_back(temp); } sort(dArray.rbegin(), dArray.rend()); while(dArray.size()!=1){ totalLength=dArray.back();//取出末尾值 ,既当前已经连接的绳子的长度 dArray.pop_back(); b=dArray.back(); dArray.pop_back(); totalLength=(totalLength+b)/2; dArray.push_back(totalLength); } cout << static_cast<int>(totalLength)<<endl; return 0; }