Editorial for 第2回卬高杯 J問題 - Hyper Tsuru Puzzle(easy)


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: admin

C++

C++20

#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
#include <algorithm>          // for copy, max
#include <functional>         // for function
#include <iostream>           // for basic_istream::operator>>, basic_ostre...
#include <memory>             // for allocator_traits<>::value_type
#include <vector>             // for vector

using namespace std;
void merge(vector<int> &x, vector<int> y)
{
    int n = x.size(), m = y.size(), ix = 0, iy = 0;
    vector<int> ret;
    while (ix < n || iy < m)
    {
        if (ix == n)
            ret.push_back(y[iy++]);
        else if (iy == m)
            ret.push_back(x[ix++]);
        else
        {
            if (x[ix] < y[iy])
                ret.push_back(x[ix++]);
            else if (x[ix] > y[iy])
                ret.push_back(y[iy++]);
            else
                ix++, iy++;
        }
    }
    x = ret;
}
int main()
{
    int n, m;
    cin >> n >> m;
    if (n == 0)
    {
        if (m == 0)
            cout << 0 << endl;
        else
            cout << 1 << endl;
        return 0;
    }
    int a[m][n];
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            cin >> a[i][j];
    int u = 1;
    vector<vector<vector<int>>> memo(n);
    for (int i = 0; i < n; i++)
    {
        memo[i].resize(u);
        u *= 3;
    }
    memo[0][0] = {0};
    function<vector<int>(int, int)> solve = [&](int d, int p) -> vector<int>
    {
        if (d < n && memo[d][p].size() > 0)
            return memo[d][p];
        auto v = solve(d - 1, p / 3);
        vector<int> w;
        for (int &e : v)
        {
            merge(w, solve(d - 1, e));
            e = 3 * e + p % 3;
        }
        auto ret = v;
        if (p % 3 == 1)
        {
            auto w0 = w, w2 = w;
            for (int &e : w0)
                e = 3 * e;
            for (int &e : w2)
                e = 3 * e + 2;
            merge(ret, w0);
            merge(ret, w2);
        }
        else
        {
            vector<int> x;
            for (int &e : w)
            {
                merge(x, solve(d - 1, e));
                e = 3 * e + 1;
            }
            auto x0 = x, x2 = x;
            for (int &e : x0)
                e = 3 * e;
            for (int &e : x2)
                e = 3 * e + 2;
            merge(ret, w);
            merge(ret, x0);
            merge(ret, x2);
        }
        return d < n ? memo[d][p] = ret : ret;
    };
    vector<int> ans;
    for (int i = 0; i < m; i++)
    {
        int p = 0;
        for (int j = 0; j < n; j++)
            p = 3 * p + a[i][j];
        merge(ans, solve(n, p));
    }
    cout << ans.size() << endl;
    for (int e : ans)
    {
        vector<int> q(n);
        for (int j = 0; j < n; j++)
        {
            q[n - 1 - j] = e % 3;
            e /= 3;
        }
        for (int j = 0; j < n; j++)
            cout << q[j] << " \n"[j == n - 1];
    }
}

Comments

There are no comments at the moment.