:::info[Description] Link. :::
:::infoSolution 很有意思的题。考虑对一个点 执行一次操作会翻转 五个点的权值,然后考虑再对这五个点做一次翻转后发现只有 五个点发生了实质的翻转。因此得到结论:做 次这样的翻转可以翻转在 意义下的 五个点的权值。因此若 取 就可以做到只翻转 一个点权值的要求。
然后直接对每个要翻转的点,倒推出整个翻转过程即可。时间复杂度为 可以通过该题。 :::
:::success[Code]
namespace lowspeed_song {
inline void init() {
}
int a[2048][2048], typ[12][2048][2048];
inline void sol() {
int n; cin >> n;
for (int i = 0; i < (1 << n); ++i)
for (int j = 0; j < (1 << n); ++j) cin >> a[i][j];
for (int i = 0; i < (1 << n); ++i)
for (int j = 0; j < (1 << n); ++j) typ[n - 1][i][j] = a[i][j];
for (int k = n - 1; k; --k)
for (int i = 0; i < (1 << n); ++i)
for (int j = 0; j < (1 << n); ++j)
if (typ[k][i][j]) {
typ[k - 1][i][j] ^= 1;
typ[k - 1][(i + (1 << (k - 1))) % (1 << n)][j] ^= 1;
typ[k - 1][(i + (1 << n) - (1 << (k - 1))) % (1 << n)][j] ^= 1;
typ[k - 1][i][(j + (1 << (k - 1))) % (1 << n)] ^= 1;
typ[k - 1][i][(j + (1 << n) - (1 << (k - 1))) % (1 << n)] ^= 1;
}
vector<pair<int, int>> res;
for (int i = 0; i < (1 << n); ++i)
for (int j = 0; j < (1 << n); ++j)
if (typ[0][i][j]) res.emplace_back(i, j);
cout << res.size() << '\n';
for (auto &[i, j] : res) cout << i << ' ' << j << '\n';
}
} // namespace lowspeed_song:::
难度:紫-
鲜活指数:8
喜欢的话,留下你的评论吧~