1603. 整数集合划分
给定一个包含 N N N个正整数的集合,请你将它划分为两个集合 A 1 A_1 A1和 A 2 A_2 A2,其中 A 1 A_1 A1 包含 n 1 n_1 n1 个元素, A 2 A_2 A2 包含 n 2 n_2 n2 个元素。
集合中可以包含相同元素。
用 S 1 S_1 S1 表示集合 A 1 A_1 A1 内所有元素之和, S 2 S_2 S2 表示集合 A 2 A_2 A2 内所有元素之和。
请你妥善划分,使得 ∣ n 1 − n 2 ∣ |n_1−n_2| ∣n1−n2∣ 尽可能小,并在此基础上 ∣ S 1 − S 2 ∣ |S_1−S_2| ∣S1−S2∣ 尽可能大。
输入格式
第一行包含整数
N
N
N。
第二行包含 N N N 个正整数。
输出格式
在一行中输出
∣
n
1
−
n
2
∣
|n_1−n_2|
∣n1−n2∣ 和
∣
S
1
−
S
2
∣
|S_1−S_2|
∣S1−S2∣,两数之间空格隔开。
数据范围
2
≤
N
≤
105
2≤N≤105
2≤N≤105,
保证集合中各元素以及所有元素之和小于
231
231
231。
输入样例1:
10
23 8 10 99 46 2333 46 1 666 555
输出样例1:
0 3611
输入样例2:
13
110 79 218 69 3721 100 29 135 2 6 13 5188 85
输出样例2:
1 9359
思路:
贪心思想:
∣
n
1
−
n
2
∣
|n_1−n_2|
∣n1−n2∣要想达到最小,我们可以思考如下:
- 当总数N是偶数的时候, n 1 = n 2 = N / 2 n_1 = n_2 = N/2 n1=n2=N/2 时, ∣ n 1 − n 2 ∣ |n_1−n_2| ∣n1−n2∣可以取到最小为 0 0 0。
- 当总数N是奇数的时候, n 1 = N / 2 , n 2 = N / 2 + 1 n_1 = N/2,n_2 = N/2 + 1 n1=N/2,n2=N/2+1 时, ∣ n 1 − n 2 ∣ |n_1−n_2| ∣n1−n2∣可以取到最小为 1 1 1。
∣ S 1 − S 2 ∣ |S_1−S_2| ∣S1−S2∣要想达到最大,我们则可以先将这 N N N个数排序,然后让前 N / 2 N/2 N/2放到 A 1 A_1 A1集合,剩余的放到 A 2 A_2 A2集合即可。
Java代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
//对数组进行排序,为后续的处理做准备
Arrays.sort(arr);
int s1 = 0,s2 = 0;
for(int i = 0; i < n/2;i++){
s1 += arr[i];
}
for(int i = n/2; i < n;i++){
s2 += arr[i];
}
System.out.println(n % 2 + " " + (s2 - s1));
}
}