E 小苯的排列构造
- 我们注意到当
n > 9
时可以有如下构造方法: 对于前面较小的数,p[i]
为i+4
i | p[i] |
---|---|
1 | 5 |
2 | 6 |
3 | 7 |
4 | 8 |
5 | 9 |
6 | 10 |
假设n为10, 那么还剩下7, 8, 9, 10还没有对应的p[i], 我们考虑将1到4和它们匹配, 即:
i | p[i] |
---|---|
7 | 1 |
8 | 2 |
9 | 3 |
10 | 4 |
如上述即为满足条件的构造
如果n为奇数, 则前一部分构造方式不变, 最后4个可以倒过来, 例如当n=11时
i | p[i] |
---|---|
8 | 4 |
9 | 3 |
10 | 2 |
11 | 1 |
- 当
n <= 9
时 显然可以暴力枚举每个排列 + 验证, 时间复杂度为(n <= 9)
暴力代码如下
vector<int> a(n);
iota(all(a), 1);
vector<bool> p(20, true);
p[0] = p[1] = p[2] = p[3] = p[5] = p[7] = p[11] = p[13] = p[17] = p[19] = false;
auto check = [&]() {
bool res = true;
for (int i = 0; i < n; i ++) {
if (!p[i + 1 + a[i]] or !p[abs(i + 1 - a[i])]) {
res = false;
break;
}
}
return res;
};
do {
if (check()) {
cout << a << endl;
return;
}
} while (next_permutation(all(a)));
cout << -1 << endl;