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.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
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