2021寒假每日一題《整數集合劃分》

整數集合劃分

題目來源: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

樣例輸入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

解題思路:貪心

題目讓兩個集合的元素 個數之差最小數值總和之差最大 ,因此儘可能均分個數。
元素個數爲偶數的時候,分開後,兩個集合元素個數同樣,差值爲 \(0\)
元素個數爲奇數的時候,分開後,元素個數差值爲 \(1\)
而後要求子集合差值儘可能大,那麼一個集合裏放小的元素,一個集合裏放大的元素就好了。
\(N\) 爲奇數的時候,不能均分,就在大元素的集合裏,多放一個元素。
具體劃分兩個集合的思路以下:排序

  • 將數組排序後,將 \([0,n/2)\) , \([n/2,n]\) 分別做爲 \(A_1\) , \(A_2\) 兩個集合。
  • 數值總和之差 = 全部元素總和 - 兩倍的 \([0,n/2)\) 區間的總和。

讀入給定的數組,邊讀入邊計算全部元素的總和。
而後減去兩倍的 \([0,n/2)\) 區間的總和,即獲得最大的數值總和之差。
個數之差根據輸入的 \(N\) 來判斷,N爲偶數則個數之差最小爲0,不然爲1。內存

解題代碼-Java

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);
    }
}
相關文章
相關標籤/搜索