#include #include #include #include using namespace std; template void log_vector(const vector& vec, const string& prefix = "") { clog << prefix; for (const T i : vec) { clog << i << " "; } clog << endl; } vector get_divisors(const int n) { vector small_divisors = {1}; vector big_factors = {n}; for (int i = 2; i * i <= n; i++) { if (n % i == 0) { small_divisors.push_back(i); big_factors.push_back(n / i); } } // reverse(small_divisors.begin(), small_divisors.end()); // big_factors.insert(big_factors.end(), small_divisors.begin(), small_divisors.end()); // return big_factors; reverse(big_factors.begin(), big_factors.end()); small_divisors.insert(small_divisors.end(), big_factors.begin(), big_factors.end()); return small_divisors; } bool verify_length_dfs(const vector& sorted_cut_sticks, const int target_length, const int remaining_length, const int original_sticks, const int remaining_sticks, size_t global_right_idx, const size_t right_idx, vector& used ) { // clog << "verify_length_dfs(" << target_length << ") " << remaining_length << " " << remaining_sticks << "x " << // global_right_idx << "->" << right_idx << endl; // log_vector(used, "used: "); if (remaining_sticks == 0) { return true; } bool result = false; for (int i = static_cast(right_idx); i >= 0; i--) { if (target_length < sorted_cut_sticks[i]) { return false; } if (used[i]) { continue; } if (remaining_length < sorted_cut_sticks[i]) { continue; } used[i] = true; if (remaining_length == sorted_cut_sticks[i]) { // 下一根 result = verify_length_dfs(sorted_cut_sticks, target_length, target_length, original_sticks, remaining_sticks - 1, global_right_idx, global_right_idx, used); } else { // 这一根 if (remaining_length == target_length) { // 这一根的第一节 global_right_idx = i; } result = verify_length_dfs(sorted_cut_sticks, target_length, remaining_length - sorted_cut_sticks[i], original_sticks, remaining_sticks, global_right_idx, i, used); } if (result) { return true; } used[i] = false; while (i >= 0 && sorted_cut_sticks[i] == sorted_cut_sticks[i - 1]) { i--; } // 剪枝 // if (remaining_sticks == original_sticks && remaining_length == target_length) { return false; } // 剪枝 if (remaining_length == target_length) { return false; } // 剪枝 } return false; } /// 需要保证 sorted_cut_sticks 有序;需要保证 target_length * remaining_sticks = 总长度 bool verify_length_dfs(const vector& sorted_cut_sticks, const int target_length, const int remaining_sticks) { vector used(sorted_cut_sticks.size(), false); bool result = verify_length_dfs(sorted_cut_sticks, target_length, target_length, remaining_sticks, remaining_sticks, sorted_cut_sticks.size() - 1, sorted_cut_sticks.size() - 1, used); // log_vector(used, "used: "); return result; } int get_shortest_original_length(vector cut_sticks) { sort(cut_sticks.begin(), cut_sticks.end()); const int total_length = accumulate(cut_sticks.begin(), cut_sticks.end(), 0); const vector divisors = get_divisors(total_length); log_vector(divisors, "divisors: "); for (const int divisor : divisors) { if (verify_length_dfs(cut_sticks, divisor, total_length / divisor)) { return divisor; } } return -1; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int cut_sticks_amount; while (cin >> cut_sticks_amount && cut_sticks_amount) { vector cut_sticks(cut_sticks_amount); for (int i = 0; i < cut_sticks_amount; i++) { cin >> cut_sticks[i]; } sort(cut_sticks.begin(), cut_sticks.end()); log_vector(cut_sticks, "cut_sticks: "); // int target_length; // cin >> target_length; // cout << (verify_length_greedy(cut_sticks, target_length) ? "Yes" : "No") << endl; cout << get_shortest_original_length(cut_sticks) << endl; } return 0; }