結果
| 問題 | No.861 ケーキカット | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2020-08-05 12:26:26 | 
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 54 ms / 1,000 ms | 
| コード長 | 2,405 bytes | 
| コンパイル時間 | 937 ms | 
| コンパイル使用メモリ | 77,560 KB | 
| 最終ジャッジ日時 | 2025-01-12 14:43:31 | 
| ジャッジサーバーID (参考情報) | judge1 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 21 | 
ソースコード
#include <iostream>
#include <numeric>
#include <vector>
struct UnionFind {
    std::vector<int> par;
    int gnum;
    explicit UnionFind(int n)
        : par(n), gnum(n) {
        std::iota(par.begin(), par.end(), 0);
    }
    void reset() {
        std::iota(par.begin(), par.end(), 0);
        gnum = par.size();
    }
    int find(int v) {
        return (par[v] == v) ? v : (par[v] = find(par[v]));
    }
    void unite(int u, int v) {
        u = find(u), v = find(v);
        if (u == v) return;
        par[v] = u;
        --gnum;
    }
};
using lint = long long;
constexpr lint INF = 1LL << 60;
bool isouter(int b) {
    static UnionFind uf(16);
    uf.reset();
    for (int i = 0; i < 16; ++i) {
        int j = i + 1;
        if (j == 16) j = 0;
        if (((b >> i) & 1) == ((b >> j) & 1)) {
            uf.unite(i, j);
        }
    }
    return uf.gnum <= 2;
}
const std::vector<int> o2i{
    0, 1, 2, 3,
    4, 9, 14, 19,
    24, 23, 22, 21,
    20, 15, 10, 5};
const std::vector<int> i2i{
    6, 7, 8,
    11, 12, 13,
    16, 17, 18};
int convert(int ob, int ib) {
    int b = 0;
    for (int i = 0; i < 16; ++i) {
        b |= ((ob >> i) & 1) << o2i[i];
    }
    for (int i = 0; i < 9; ++i) {
        b |= ((ib >> i) & 1) << i2i[i];
    }
    return b;
}
constexpr int N = 5;
constexpr int M = N * N;
bool connected(int b) {
    static UnionFind uf(M);
    uf.reset();
    for (int i = 0; i < M; ++i) {
        for (auto d : {1, N}) {
            int j = i + d;
            if (j < M && ((b >> i) & 1) == ((b >> j) & 1)) {
                uf.unite(i, j);
            }
        }
    }
    return uf.gnum == 2;
}
void solve() {
    std::vector<lint> xs(M);
    for (auto& x : xs) std::cin >> x;
    lint ans = INF;
    for (int ob = 0; ob < (1 << 16); ++ob) {
        if (!isouter(ob)) continue;
        for (int ib = 0; ib < (1 << 9); ++ib) {
            int b = convert(ob, ib);
            if (!connected(b)) continue;
            lint score = 0;
            for (int i = 0; i < M; ++i) {
                if ((b >> i) & 1) {
                    score += xs[i];
                } else {
                    score -= xs[i];
                }
            }
            ans = std::min(ans, std::abs(score));
        }
    }
    std::cout << ans << "\n";
}
int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    solve();
    return 0;
}
            
            
            
        