题解 | #小苯的排列构造# 牛客周赛 Round 44 E
小苯的排列构造
https://ac.nowcoder.com/acm/contest/82526/E
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;
查看7道真题和解析
腾讯公司福利 1138人发布