// 決定的&N=38 の別解 // アイデア:snuke // 実装:chatGPT #include using namespace std; using i128 = __int128_t; const int N = 38; vector> get_candidates() { vector> v; // 右側の斜め列 for (int r = 1; r + 2 < N; ++r) { v.emplace_back(r, r + 2); } // 左側の斜め列 for (int r = 2; r < N; ++r) { v.emplace_back(r, r - 1); } return v; } vector make_grid( const vector>& cand, const vector& use ) { vector g(N, string(N, '.')); g[1][1] = '#'; // (2,2) g[1][2] = '#'; // (2,3) g[5][0] = '#'; // (6,1) for (int i = 0; i < (int)cand.size(); ++i) { auto [r, c] = cand[i]; g[r][c] = use[i] ? 'P' : '#'; } return g; } // P をちょうど1個通る経路数 i128 count_paths(const vector& g) { static i128 dp[N][N][2]; memset(dp, 0, sizeof(dp)); dp[0][0][0] = 1; for (int r = 0; r < N; ++r) { for (int c = 0; c < N; ++c) { if (r == 0 && c == 0) continue; if (g[r][c] == '#') continue; int add = (g[r][c] == 'P'); for (int s = 0; s + add <= 1; ++s) { i128 x = 0; if (r > 0) x += dp[r - 1][c][s]; if (c > 0) x += dp[r][c - 1][s]; dp[r][c][s + add] += x; } } } return dp[N - 1][N - 1][1]; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); auto cand = get_candidates(); int K = cand.size(); // 全候補を P にしたときから、 // 1個だけ # にしたときの減少量を重みとする。 vector all(K, 1); i128 base = count_paths(make_grid(cand, all)); vector> weight; for (int i = 0; i < K; ++i) { all[i] = 0; i128 cur = count_paths(make_grid(cand, all)); all[i] = 1; weight.emplace_back(base - cur, i); } sort(weight.begin(), weight.end()); int T; cin >> T; while (T--) { unsigned long long M; cin >> M; i128 rem = M; vector use(K, 0); // 重み列は complete sequence なので降順 greedy でよい for (int i = K - 1; i >= 0; --i) { auto [w, id] = weight[i]; if (w <= rem) { rem -= w; use[id] = 1; } } assert(rem == 0); auto g = make_grid(cand, use); cout << N << '\n'; for (auto& s : g) { cout << s << '\n'; } } }