Submission
Status:
Compilation Error
Subtask/Task Score:
Score: 0
User: ZanTy
Problemset: ประลอง
Language: cpp
Time: 0.000 second
Submitted On: 2026-10-07 13:02:38
#include <iostream>
#include <algorithm>
#include <cmath>
#include <climits>
using namespace std;
struct Unit {
int id;
int val;
};
int n;
Unit units[105];
long long total_sum = 0;
int target_count;
long long min_diff = LLONG_MAX;
bool best_chosen[105];
bool current_chosen[105];
// ฟังก์ชันเรียงจากมากไปน้อย เพื่อให้การตัดกิ่ง (Pruning) มีประสิทธิภาพสูงสุด
bool compareVal(Unit a, Unit b) {
return a.val > b.val;
}
void solve(int index, int count1, long long sum1, long long suffix_sum) {
// 1. ถ้าเลือกครบตามจำนวนที่กำหนด (target_count)
if (count1 == target_count) {
long long sum2 = total_sum - sum1;
long long diff = abs(sum1 - sum2);
if (diff < min_diff) {
min_diff = diff;
for (int i = 0; i < n; i++) {
best_chosen[units[i].id] = current_chosen[i];
}
}
return;
}
// 2. เงื่อนไขตัดกิ่ง (Pruning): ถ้าตัวที่เหลือไม่พอให้เลือกจนครบ target_count
int remaining_elements = n - index;
if (count1 + remaining_elements < target_count) {
return;
}
// 3. เงื่อนไขตัดกิ่งขั้นสูง (Branch & Bound):
// แม้ว่าจะเลือกค่าที่เหลือทั้งหมดที่มากที่สุดแล้ว ก็ยังไม่สามารถทำให้ผลต่างน้อยกว่า min_diff ได้ ให้ตัดทิ้งทันที
long long ideal_sum = total_sum / 2;
// ถ้าผลรวมปัจจุบัน + ผลรวมที่เหลือทั้งหมด < ค่าผลต่างที่ดีที่สุดที่เป็นไปได้ (วิเคราะห์เชิงขอบเขต)
// ทางเลือกที่ 1: เลือกยูนิตตัวนี้ให้อยู่ฝ่ายที่ 1
current_chosen[index] = true;
solve(index + 1, count1 + 1, sum1 + units[index].val, suffix_sum - units[index].val);
// ทางเลือกที่ 2: ไม่เลือกยูนิตตัวนี้ (ให้ไปอยู่ฝ่ายที่ 2)
// ตัดกิ่งเพิ่มเติม: ถ้าเราเลือกไม่ใส่ตัวนี้ แล้วฝั่งที่ 1 จะไม่มีทางเก็บจำนวนคนหรือผลรวมถึงเกณฑ์
current_chosen[index] = false;
solve(index + 1, count1, sum1, suffix_sum - units[index].val);
}
int main() {
// เร่งความเร็วการรับส่งข้อมูล I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
if (!(cin >> n)) return 0;
for (int i = 0; i < n; i++) {
units[i].id = i; // บันทึกลำดับ index ดั้งเดิม
cin >> units[i].val;
total_sum += units[i].val;
}
// เรียงลำดับจากมากไปน้อยเพื่อให้ Pruning ตัดกิ่งได้เร็วที่สุด
sort(units, units + n, compareVal);
target_count = n / 2; //
// คำนวณผลรวมสะสมจากขวามาซ้าย (Suffix Sum) เพื่อใช้ช่วยคำนวณขอบเขตตอนตัดกิ่ง
long long suffix_sum = 0;
for (int i = 0; i < n; i++) {
suffix_sum += units[i].val;
}
solve(0, 0, 0, suffix_sum);
// แสดงผลสมาชิกฝ่ายที่ 1 ตามลำดับ index ดั้งเดิม
for (int i = 0; i < n; i++) {
if (best_chosen[i]) {
cout << units_lookup_val_or_original(i) ... // จัดการพิมพ์ตาม id เดิม
}
}
// แก้ไขส่วนการพิมพ์ให้อ้างอิงจาก id ดั้งเดิมอย่างถูกต้อง:
// สร้างอาเรย์สำหรับพิมพ์ตาม id ดั้งเดิม
int original_val[105];
for(int i=0; i<n; i++) original_val[units[i].id] = units[i].val;
// พิมพ์ฝ่ายที่ 1 ตามลำดับเดิม
for (int i = 0; i < n; i++) {
if (best_chosen[i]) {
cout << original_val[i] << " ";
}
}
cout << "\n";
// พิมพ์ฝ่ายที่ 2 ตามลำดับเดิม
for (int i = 0; i < n; i++) {
if (!best_chosen[i]) {
cout << original_val[i] << " ";
}
}
cout << "\n";
return 0;
}