题目来源:PAT甲级真题1113
时间限制:\(1000ms\) 内存限制:\(64mb\)java
给定一个包含 \(N\) 个正整数的集合,请你将它划分为两个集合 \(A_1\) 和 \(A_2\),其中 \(A_1\) 包含 \(n_1\) 个元素,\(A_2\) 包含 \(n_2\) 个元素。
集合中能够包含相同元素。
用 \(S_1\) 表示集合 \(A_1\) 内全部元素之和,\(S_2\) 表示集合 \(A_2\) 内全部元素之和。
请你妥善划分,使得 \(|n_1−n_2|\) 尽量小,并在此基础上 \(|S_1−S_2|\) 尽量大。shell
第一行包含整数 \(N\) 。
第二行包含 \(N\) 个正整数。数组
在一行中输出 \(|n_1−n_2|\) 和 \(|S_1−S_2|\) ,两数之间空格隔开。spa
\(2 ≤ N ≤ 10^5\) ,
保证集合中各元素以及全部元素之和小于 \(2^{31}\) 。code
10 23 8 10 99 46 2333 46 1 666 555
0 3611
13 110 79 218 69 3721 100 29 135 2 6 13 5188 85
1 9359
题目让两个集合的元素 个数之差最小 , 数值总和之差最大 ,因此尽可能均分个数。
元素个数为偶数的时候,分开后,两个集合元素个数同样,差值为 \(0\) 。
元素个数为奇数的时候,分开后,元素个数差值为 \(1\) 。
而后要求子集合差值尽可能大,那么一个集合里放小的元素,一个集合里放大的元素就好了。
\(N\) 为奇数的时候,不能均分,就在大元素的集合里,多放一个元素。
具体划分两个集合的思路以下:排序
读入给定的数组,边读入边计算全部元素的总和。
而后减去两倍的 \([0,n/2)\) 区间的总和,即获得最大的数值总和之差。
个数之差根据输入的 \(N\) 来判断,N为偶数则个数之差最小为0,不然为1。内存
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt(); int[] a = new int[n]; long s = 0; for (int i = 0; i < n; i++) { a[i] = input.nextInt(); s += a[i]; } input.close(); Arrays.sort(a); for (int i = 0; i < n / 2; i++) { s -= 2L * a[i]; } System.out.printf("%d %d\n", n % 2, s); } }