Codeforces Round 812 (Div. 2) C. Build Permutation
Codeforces 题解 - [Codeforces Round 812 (Div. 2)C. Build Permutation]
题目描述
A \(\mathbf{0}\)-indexed array \(a\) of size \(n\) is called good if for all valid indices \(i\) (\(0 \le i \le n-1\)), \(a_i + i\) is a perfect square\(^\dagger\).
Given an integer \(n\). Find a permutation\(^\ddagger\) \(p\) of \([0,1,2,\ldots,n-1]\) that is good or determine that no such permutation exists.
\(^\dagger\) An integer \(x\) is said to be a perfect square if there exists an integer \(y\) such that \(x = y^2\).
\(^\ddagger\) An array \(b\) is a permutation of an array \(a\) if \(b\) consists of the elements of \(a\) in arbitrary order. For example, \([4,2,3,4]\) is a permutation of \([3,2,4,4]\) while \([1,2,2]\) is not a permutation of \([1,2,3]\).
输入格式
Input
The first line contains a single integer \(t\) (\(1 \le t \le 10^4\)) — the number of test cases.
The only line of each test case contains a single integer \(n\) (\(1 \le n \le 10^5\)) — the length of the permutation \(p\).
It is guaranteed that the sum of \(n\) over all test cases does not exceed \(10^5\).
输出格式
Output
For each test case, output \(n\) distinct integers \(p_0, p_1, \dots, p_{n-1}\) (\(0 \le p_i \le n-1\)) — the permutation \(p\) — if the answer exists, and \(-1\) otherwise.
题目大意
给定一个长度为n的数组,数组中的元素为\([0,1,2,\ldots,n-1]\),要求数组中每个元素加上其下标后为一个完全平方数。即\(a_i + i\)为一个完全平方数。
输入
3
3
4
7
输出
1 0 2
0 3 2 1
1 0 2 6 5 4 3
解题思路
-
所有情况均数组均存在
-
在[n, 2n]中一定存在至少一个完全平方数 即\(n < \lceil \sqrt{n} \rceil ^2 \leq 2n\)
证明引用
易得
两边平方
我们希望
即
设\(\sqrt{n} = x, x \in [0, \infty].\)
解得两根
则当n大于等于6时,\(n + 2\sqrt{n} + 1 \leq 2n\)成立
易知
得证
- 递归
设h为不超过k的最小平方数,因此 \(h \leq 2k\),也就是\(h - k \leq k\)
因此我们可以用\(p_{i} = h - i\)来填充\((h - k \leq i \leq k)\).使用这种方法,我们可以递归地将k减少到h - k - 1. 然后一直减到 -1。
我们可以证明 \(h - k \geq 0\) 因为 \(h \geq k\)
代码实现
#include "bits/stdc++.h"
using namespace std;
constexpr int Mxn = 1e5 + 10;
void Solution()
{
int n;
cin >> n;
vector<int> a(n);
function<void(int)> Recurse = [&](int r)
{
// cout << "r = " << r << '\n';
if(r < 0) return;
int h = sqrt(2 * r);
h *= h;
int l = h - r;
Recurse(l - 1);
for(;l <= r;++l, --r)
{
a[l] = r;
a[r] = l;
}
};
Recurse(n - 1);
for(auto x : a) cout << x << ' '; cout << '\n';
return;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--)
Solution();
return 0;
}
/*
1
1
2
3
4
5
6
7
8
9
10
*/

浙公网安备 33010602011771号