杭电新生赛 大雪球 二分

‍ 题目地址

✨ AC code

import java.io.*;
import java.util.*;

public class Main
{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	static int N = (int) 2e5 + 10, n;
	static long k;
	static long[] a = new long[N];

	public static void main(String[] args) throws IOException
	{
		int T = Integer.parseInt(in.readLine());
		while (T-- > 0)
		{
			n = Integer.parseInt(in.readLine());
			String[] ss = in.readLine().split(" ");
			for (int i = 0; i < n; i++)
				a[i] = Long.parseLong(ss[i]);
			Arrays.sort(a, 0, n);
			k = Long.parseLong(in.readLine());
			long l = a[0] + a[1];
			long r = a[n - 1] + a[n - 2];
			while (l < r)
			{
				long m = l + r >> 1;
				if (check(m))
					r = m;
				else
					l = m + 1;
			}
			out.write(l - 1 + "\n");
		}
		out.flush();
	}

	private static boolean check(long x)
	{
		long cnt = 0;
		int t = n - 1;// 记录上一次选取的雪球下标
		for (int i = 0; i < n; i++)
		{
			int j;
			for (j = t; j > i; j--)
				if (x > a[i] + a[j])// x > a[j] + a[i] 说明从a[i] 和 a[i+1,j] 的和都小于 x
					break;
			cnt += j - i;
			t = j;// a[i] 是递增的,当前的 a[i] + a[j+1] 不符合小于 x 的条件,下一轮的 j 就可以从 当前的 j 开始了
			if (cnt >= k)
				return true;
		}
		return false;
	}
}

你可能感兴趣的:(算法题解,android)