Submission

Status:

P-PP-PP--P

Subtask/Task Score:

60/100

Score: 60

User: loop

Problemset: ประลอง

Language: cpp

Time: 0.004 second

Submitted On: 2026-10-10 18:34:02

#include <cstdio>
#include <vector>
using namespace std;

// Pick n/2 units (rounded down) for side 1 so the two sums are as close as possible.
// par[c][s] = the unit that first made "c units with sum s" reachable; following it back rebuilds the choice.
int main() {
    int n, v[105], V = 0;
    long long total = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &v[i]);
        total += v[i];
        int a = v[i] < 0 ? -v[i] : v[i];
        if (a > V) V = a;
    }
    int k = n / 2, off = k * V, width = 2 * off + 1;
    vector<vector<signed char> > par(k + 1, vector<signed char>(width, 0));
    par[0][off] = -1;                                   // empty choice, sum 0
    for (int i = 1; i <= n; i++)
        for (int c = (i < k ? i : k); c >= 1; c--)
            for (int s = 0; s < width; s++) {
                if (par[c - 1][s] == 0) continue;
                int t = s + v[i];
                if (t < 0 || t >= width || par[c][t] != 0) continue;
                if (par[c - 1][s] == -1 && c - 1 != 0) continue;
                par[c][t] = (signed char)i;
            }
    int best = -1;
    long long bestDiff = 0;
    for (int s = 0; s < width; s++) {
        if (par[k][s] == 0) continue;
        long long sum1 = s - off, d = total - 2 * sum1;
        if (d < 0) d = -d;
        if (best < 0 || d < bestDiff) { best = s; bestDiff = d; }
    }
    bool pick[105] = {false};
    int s = best;
    for (int c = k; c >= 1; c--) {
        int i = par[c][s];
        pick[i] = true;
        s -= v[i];
    }
    bool first = true;
    for (int i = 1; i <= n; i++) if (pick[i]) { printf(first ? "%d" : " %d", v[i]); first = false; }
    printf("\n");
    first = true;
    for (int i = 1; i <= n; i++) if (!pick[i]) { printf(first ? "%d" : " %d", v[i]); first = false; }
    printf("\n");
    return 0;
}