AtCoder Beginner Contest 427

链接:https://atcoder.jp/contests/abc427

A – ABC -> AC

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    string s;
    cin >> s;

    for (int i = 0; i < s.size(); ++i)
    {
        if (i == s.size() / 2)
            continue;

        cout << s[i];
    }

    cout << endl;
}

B – Sum of Digits Sequence

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    ll n;
    cin >> n;
    vector<int> a(100);
    a[0] = 1;
    ll sum = 0;
    for (int i = 1; i <= n; ++i)
    {
        ll cur = 0;

        int x = a[i - 1];
        while (x)
            cur += x % 10, x /= 10;

        sum += cur;
        a[i] = sum;
    }

    cout << a[n] << endl;
}

C – Bipartize

算法:

    暴搜,状态压缩。

思路:

    由于 \(n\) 只有 \(10\),考虑直接暴搜每个点的颜色。

    使用状态压缩,对于 \(u\) 点 \(1\) 代表黑,\(0\) 代表白。

    对于每种状态,枚举图上的所有边,累加所有相连且不相等的边,并更新全局最大答案,此时答案存储最大成立边数,最后答案就为 \(m – ans\)。

关键代码:

void miyan()
{
    int n, m;
    cin >> n >> m;
    vector<pii> g(m);
    for (int i = 0; i < m; ++i)
    {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g[i] = {u, v};
    }

    int ans = 0;
    for (int mask = 0; mask < (1 << n); ++mask)
    {
        int cnt = 0;
        for (auto [u, v] : g)
        {
            if ((mask >> u & 1) ^ (mask >> v & 1))
                ++cnt;
        }

        ans = max(ans, cnt);
    }

    cout << m - ans << endl;
}

D – The Simple Game

算法:

    \(dp\),记忆化搜索。

思路:

    当前操作的人想赢等价于下一个人怎么操作都是输。

    使用记忆化搜索。

    \(dp[u][now]\): 当前在 \(u\) 节点,前面已经走了 \(now\) 步,\(Alice\) 是否可以保证必赢。

    状态转移:

  • 边界情况,当前已经走了 \(k + k\) 步,判断最后棋子落在 'A' 则 \(Alice\) 胜利,否则 \(Bob\) 胜利。
  • 对于所有与点 \(u\) 想连的点 \(v\):
    • 如果当前是 \(Alice\) 执行:
      • 他如果想赢就需要走一个后续节点可以赢的节点,只要有一个 \(v\) 能赢就走这个节点,既递归判断 \((v, now + 1)\) 的状态是否为 \(true\)。
      • 如果后续节点都返回 \(false\) 就说明只能返回 \(false\)。
    • 如果当前是 \(Bob\) 执行:
      • 他如果想赢就需要走一个后续节点可以让 \(Alice\) 输的节点,只要有一个 \(v\) 可以让 \(Alice\) 输,就走这个节点,既递归判断 \((v, now + 1)\) 的状态是否为 \(false\)。
      • 如果所有后继状态都 \(true\),说明无论 \(Bob\) 怎么选,\(Alice\) 都能赢。

关键代码:

void miyan()
{
    int n, m, k;
    string s;
    cin >> n >> m >> k >> s;
    vector<vector<int>> g(n + 1);
    while (m--)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
    }

    s = ' ' + s;

    vector dp(n + 1, vector<int>(k + k + 1, -1));
    auto dfs = [&](auto &&self, int u, int now) -> bool
    {
        auto &cur = dp[u][now];

        if (cur != -1)
            return cur;

        if (now == k + k)
            return (cur = (s[u] == 'A'));

        for (auto v : g[u])
        {
            if (now % 2)
            {
                if (!self(self, v, now + 1))
                    return cur = 0;
            }
            else
            {
                if (self(self, v, now + 1))
                    return cur = 1;
            }
        }

        return cur = now % 2;
    };

    cout << (dfs(dfs, 1, 0) ? "Alice" : "Bob") << endl;
}

E – Wind Cleaning

算法:

    \(bfs\),最短路。

思路:

    观察到 \(n\) 和 \(m\) 都很小,直接使用 \(bfs\) 跑最短路,队列存储当前地图和步数。

关键代码:

void miyan()
{
    int n, m;
    cin >> n >> m;
    vector<string> s(n);
    for (auto &x : s)
        cin >> x;

    auto bfs = [&]() -> int
    {
        queue<pair<vector<string>, int>> q;
        set<vector<string>> hash;
        q.push({s, 0});
        hash.insert(s);

        while (q.size())
        {
            auto [t, cnt] = q.front();
            q.pop();

            ll sum = 0;
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < m; ++j)
                    sum += (t[i][j] == '#');

            if (!sum)
                return cnt;

            for (int d = 0; d < 4; ++d)
            {
                vector<string> v(n, string(m, '.'));
                for (int i = 0; i < n; ++i)
                {
                    for (int j = 0; j < m; ++j)
                    {
                        if (t[i][j] == '#')
                        {
                            int a = i + dx[d], b = j + dy[d];

                            if (a < 0 || a >= n || b < 0 || b >= m)
                                continue;

                            if (t[a][b] == 'T')
                                goto NEXt;

                            v[a][b] = '#';
                        }
                        else if (t[i][j] == 'T')
                            v[i][j] = 'T';
                    }
                }

                if (hash.count(v))
                    continue;
                hash.insert(v);
                q.push({v, cnt + 1});
            NEXt:;
            }
        }

        return -1;
    };

    cout << bfs() << endl;
}

F – Not Adjacent

    折半搜索以后再补。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇