Build Permutation
题面翻译
我们认为一个序列 a a a 是优秀的,当且仅当其任意一个元素加上其下标是完全平方数。
形式化地, ∀ i ∈ [ 0 , n ) , a i + i ∈ N \forall i\in[0,n), \sqrt{a_i+i}\in\mathbb{N} ∀i∈[0,n),ai+i∈N 。
给定 n n n,求 0 0 0 至 n − 1 n-1 n−1 的一个优秀排列,或者判断不存在这样的排列。
值得注意的是,本题中特殊规定下标从 0 0 0 开始,到 n − 1 n-1 n−1 结束。
多测, ∑ n ≤ 1 0 5 \sum n\leq10^5 ∑n≤105 。
样例输入 #1
3
3
4
7
样例输出 #1
1 0 2
0 3 2 1
1 0 2 6 5 4 3
分析
我们从 n − 1 n - 1 n−1 开始考虑递归处理此题,设当前的数为 x x x,找到比它大的完全平方数中最小的那个 k k k,那么 k = ⌈ n ⌉ 2 k = \left \lceil \sqrt{n} \right \rceil ^2 k=⌈n⌉2, a x a_x ax 到 a x − k a_{x-k} ax−k 则可以依次填入 k − x , . . . , x k - x,...,x k−x,...,x,再继续递归处理 k − x − 1 k - x - 1 k−x−1 即没填完的部分。
AC code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
inline void init(int x) {
if (x < 0) return ;
int k = ceil(sqrt(x)); k = k * k;
init(k - x - 1);
for (int i = x; i >= k - x; i -- ) cout << i << " ";
}
signed main() {
// freopen("C.in","r",stdin);
// freopen("C.out","w",stdout);
int t;
cin >> t;
while (t -- ) {
cin >> n;
init(n - 1);
cout << endl;
}
return 0;
}
求赞,感谢阅读