更佳的阅读体验:洛谷 P10312 题解
简要题意:给定一个栅栏密码及其高度,求其明文字符串。
数据范围比较小,因此我们可以考虑直接将密文字符串还原到二维数组里,然后计算每个字符在明文中的出现位置。
具体地,我们在网格图上标记好“栅栏”中每个字符在密文字符串中出现的位置,然后按照“栅栏”的顺序遍历,输出即可。
#include <iostream>
using namespace std;
const int N = 15, M = 1e5 + 10, pos[9][18] = {
{1, 2},
{1, 2, 3, 2},
{1, 2, 3, 4, 3, 2},
{1, 2, 3, 4, 5, 4, 3, 2},
{1, 2, 3, 4, 5, 6, 5, 4, 3, 2},
{1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2},
{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2}
};
int h, n, tot, c[N][M];
string s;
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cin >> h >> s;
n = s.size();
for (int i = 0; i < n; ++i) c[pos[h - 2][i % ((h << 1) - 2)]][i + 1] = 1;
for (int i = 1; i <= h; ++i)
for (int j = 1; j <= n; ++j) if (c[i][j]) c[i][j] = tot++;
for (int i = 0; i < n; ++i) cout << s[c[pos[h - 2][i % ((h << 1) - 2)]][i + 1]];
return 0;
}