题目描述:
题目大意:生成一个排列,使得 i + ai 为完全平方数。
数学:
定理: [n,2*n] 区间中必定存在一个完全平方数。
考虑递归。
我们从最后一个元素 n - 1,找到不小于它的第一个完全平方数,假如是 h, 那么 h <= 2*(n-1)
然后再从两端开始构造。例如 假设 a 的平方等于 h: ..........[ ..... ] 我想要黄色的这一段 ai 与 i 相加都等于 h。因为最大的数是 r(r是右边界处的下标), 所以最小的左边界应该是 h - r,这样我们可以交错相加,使得这些下标处都满足条件,即 ai + i = h。然后递归调用。
const int N = 1e5 + 5;
int n, ans[N];
void recurse(int r) {
if (r < 0) return;
int s = sqrt(2 * r); s *= s;
int l = s - r; recurse(l - 1);
for (; l <= r; l++, r--) {
ans[l] = r; ans[r] = l;
}
}
int main() {
int t;
cin >> t;
while (t--) {
int n; cin >> n;
recurse(n - 1);
for (int i = 0; i < n; i++)
cout << ans[i] << " ";
cout << endl;
}
}