面白かった
問題概要
という 個の整数がある。これらを 2 個以上のグループに分ける。各グループの整数の総和が互いに等しくなるようにグループ分けすることが可能かどうかを判定し、可能ならば具体例を構築せよ。
制約
考えたこと
こういうのはいろんな で試していくのがよさそう。
- はダメ
- もダメ
- は (1, 7), (3, 5) で OK
- はダメ
- は (1, 11), (3, 9), (5, 7) で OK
この辺りでとりあえず
- 2 以外の偶数は OK
- 素数はダメ
といったことが見えてきた。2 以外の偶数は、(2i+1, 2N-2i-1) を並べれば OK。素数は、仮に可能だとすると、グループの個数を 、各グループの総和を とすると、
となる。 は素数なので だと 、 しかありえないけど、これもダメ。よって素数はダメ。
素数でない奇数のとき
多分いろんな方法があるけど、 と表せる場合に帰着させて考えることにした。 が 3 の倍数でなかったとしても、 としたとき、
- まず最初の 個を 3 個ずつの グループに分ける。
- 残りの 個を グループに振り分けていく
という風にできる。よって、 の場合ができれば OK。これは色々手を動かしていると、できた (下のコード参照)!
コード
#include <bits/stdc++.h> using namespace std; bool is_prime(long long n) { if (n <= 1) return false; for (long long p = 2; p * p <= n; ++p) { if (n % p == 0) return false; } return true; } void print(vector<vector<int>> res) { cout << res.size() << endl; for (auto v : res) { sort(v.begin(), v.end()); cout << v.size(); for (auto p : v) cout << " " << p; cout << endl; } } vector<vector<int>> sub(int W) { vector<vector<int>> res; int sum = W * 9; for (int i = 0; i < W; ++i) { int a = i*2 + 1; int j = (i + W/2) % W; int b = W*2+1 + j*2; int c = sum - a - b; res.push_back(vector<int>({a, b, c})); } return res; } int num(int h, int w, int W) { int id = h * W + w; return id * 2 + 1; } bool check(vector<vector<int>> res) { set<long long> se; for (auto v : res) { long long sum = 0; for (auto p : v) sum += p; se.insert(sum); } return se.size() == 1; } void solve(int N) { if (is_prime(N)) { cout << "impossible" << endl; return; } long long H = 3, W = 1; for (; H * H <= N; ++H) { if (N % H == 0) { W = N / H; break; } } vector<vector<int>> res; if (N % 2 == 0) { for (int i = 1, j = N*2-1; i <= j; i += 2, j -= 2) { res.push_back(vector<int>({i, j})); } print(res); return; } res = sub(W); int width = (H - 3) / 2; for (int i = 0; i < W; ++i) { for (int j = 0; j < width; ++j) { int h = j + 3; int w = i; res[i].push_back(num(h, w, W)); } for (int j = 0; j < width; ++j) { int h = j + width + 3; int w = W - i - 1; res[i].push_back(num(h, w, W)); } } print(res); } int main() { int N; while (cin >> N) solve(N); }