题目链接
给定一段一段的绳子,你需要把它们串成一条绳。每次串连的时候,是把两段绳子对折,再如下图所示套接在一起。这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连。每次串连后,原来两段绳子的长度就会减半。
给定 N 段绳子的长度,你需要找出它们能串成的绳子的最大长度。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 N (2≤N≤104);第 2 行给出 N 个正整数,即原始绳段的长度,数字间以空格分隔。所有整数都不超过104 。
输出格式:
在一行中输出能够串成的绳子的最大长度。结果向下取整,即取为不超过最大长度的最近整数。
输入样例:
8
10 15 12 3 4 13 1 15
输出样例:
14
一开始我想着如果要绳子长度最长,肯定要先把短的给对折,然后我以为短的对折后,有可能会排在原来数组的后面,所以用了一个优先队列来储存绳子长度
优先队列AC代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(bf);
in.nextToken();
int N = (int) in.nval;
PriorityQueue<Double> q = new PriorityQueue<Double>();
for (int i = 0; i < N; i++) {
in.nextToken();
q.add(in.nval);
}
while (q.size() > 1) {
double a = q.poll();
double b = q.poll();
double l = (a + b) / 2.0;
q.add(l);
}
double r = q.peek();
out.print((int) r);
out.flush();
}
}
后来思考了一下,如果两个数的和的一半要大于第三个数,那么其中至少有一个
a<c,b<c → a+b<2c
普通做法AC代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(bf);
in.nextToken();
int N = (int) in.nval;
double[] s = new double[N];
for (int i = 0; i < N; i++) {
in.nextToken();
s[i] = in.nval;
}
Arrays.sort(s);
double sum = s[0];
for (int i = 1; i < N; i++) {
sum = (sum + s[i]) / 2.0;
}
out.print((int) sum);
out.flush();
}
}
扩展
如果要求折叠后的最小值,与之前的代码类似,写一个Comparator,重写compare方法,创建优先队列的时候把Comparator对象传入。
Comparator<Double> cmp = new Comparator<Double>() {
@Override
public int compare(Double o1, Double o2) {
if (o2 > o1) {
return 1;
} else {
return -1;
}
}
};
PriorityQueue<Double> q = new PriorityQueue<Double>(cmp);