ICPC2023 参加記

ICPC2023 国内予選 参加記録

順位表: https://icpcsec.firebaseapp.com/standings/

4完で48位で予選通過です。うおおお!!!

当日

第一志望の研究室の教授に相談したら研究室でICPCに参加してよいことになりました。 またPCやディスプレイやマウスやプリンターも使っていいよと言ってもらえとても助かりました。

ICPC開始30分前に研究室配属の結果が出て、無事そこの研究室への配属が確定しました。

ICPC

Aをえくとくんに投げて、Bをチラ見し、面倒そうなのでC, D, Eに目を通しました。

CをAckvyくんと考えます。市松模様を書いて黒いところは固定したまま、それ以外を動かすとよさそうと話して、偶数の時は上下左右分割し斜めにswapすれば良いね、奇数のときはいい感じに反転したりしてからswapすればいいねという話になります。気づいたらえくとくんがBまで通していました。

Cの実装が嫌なのでえくとくんに方針を伝えて投げました。怖いので手元でジャッジを書いたほうが良さそうだよねと話してジャッジも書いてもらいました。すべての実装を投げました。その間にAckvyくんとEを考えますが上手く方針が立ちません。貪欲にできないかなぁ~みたいなことを話したのですが、上手く行かなさそうでした。

Cがまだ通っていなかったので見に行きます。手元で回して偶数の時はOKですが奇数のときはインデックス回りが壊れていそうだったので変わって僕が書くことになりました。なんとか書いたのですが0が出現したりで発狂していました。修正したのですが、手元で回すとWAになってしまいました。 よく見ると奇数のなかでも $4n + 3$ のときに壊れていました。Ackvyくんと考察をし直します。 真ん中の列をいい感じにswapするといいねぇという話になり実装して提出します。WAります。え? 僕の実装が間違っていました。ごめん… 修正して投げてACです。この時点で残りが30分で、予選落ちたな…と絶望ぎみでした。

DはAckvyくんが「これって8以下にできませんか?」という天才発言をしたことにより、dfsしながら枝刈り全探索すればよくない?という話になります。残りが30分なのでめちゃめちゃ急いで実装します。

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i, n) for (ll i = 0; i < (n); i++)

bool solve() {
    ll N;
    cin >> N;
    if (N == 0) return false;
    string S;
    cin >> S;
    ll ans = 8;

    vector<ll> v = {};
    ll sum = 0;
    auto check = [&]() -> bool {
        ll m = v.size();
        set<ll> s;
        rep(msk, 1 << m) {
            ll add = 0;
            rep(j, m) {
                if ((msk >> j) & 1) add += v[j];
            }
            s.insert(add);
        }
        rep(i, N + 1) if (S[i] == 'o') {
            if (s.count(i) == 0) return false;
        }
        return true;
    };

    auto dfs = [&](auto&& self) {
        if (sum == N) {
            if (check()) {
                ans = min(ans, (ll)v.size());
            }
            return;
        }
        if (v.size() >= ans) return;
        ll b = (v.empty() ? 1 : v.back());
        for (ll add = b; sum + add <= N; add++) {
            v.push_back(add);
            sum += add;
            self(self);
            sum -= add;
            v.pop_back();
        }
    };

    dfs(dfs);

    cout << ans << endl;
    return true;
}

int main() {
    while (solve())
        ;
}

実行したらちょっと時間がかかってううううう…となりましたが、1分くらい待ったら無事終わりました。投げたらACでした。わーい! Cを通してから12分くらいでDを通しました、これにより予選通過が確定しました。天才すぎ!!

打ち上げ

近くのお好み焼き屋さんにいきました。おいしかったです!

まとめ

予選通過できて本当に良かったです。去年から順位が上がっていていい感じです。来年はもっと上に行けるといいなぁ…

Comment is disabled to avoid unwanted discussions from 'localhost:1313' on your Disqus account...

Theme Name