给定一个数n,构造{0,1,2,…,n-1}的一个排列
a
0
,
a
1
,
.
.
.
,
a
n
−
1
{a_0,a_1,...,a_{n-1}}
a0,a1,...,an−1,使得
对于任意的
0
<
=
i
<
n
0<=i
一个数x为平方数,当且仅当存在一个数y,使得
x
=
y
2
x=y^2
x=y2
定理:
对于任意的非负数n,区间[n,2n]至少存在一个完全平方数。
证明:
当n为0,1,2,3,4时,完全平方数分别为0,1,4,4,4。
当n>=5时,
因为 ⌈ n ⌉ ≤ n + 1 \lceil \sqrt{n} \rceil \leq \sqrt{n}+1 ⌈n⌉≤n+1 ,有
⌈ n ⌉ 2 ≤ n + 2 n + 1 \lceil \sqrt{n} \rceil^2 \leq n+2\sqrt{n}+1 ⌈n⌉2≤n+2n+1
又因为
n
−
(
2
n
+
1
)
=
n
−
2
n
−
1
=
(
n
−
1
)
2
−
2
>
=
(
5
−
1
)
2
−
2
>
0
n-(2\sqrt{n}+1)=n-2\sqrt{n}-1=(\sqrt{n}-1)^2-2>=(\sqrt{5}-1)^2-2>0
n−(2n+1)=n−2n−1=(n−1)2−2>=(5−1)2−2>0
,所以:
n
<
=
⌈
n
⌉
2
≤
n
+
2
n
+
1
≤
2
∗
n
n<=\lceil \sqrt{n} \rceil^2 \leq n+2\sqrt{n}+1 \leq 2*n
n<=⌈n⌉2≤n+2n+1≤2∗n
所以区间[n,2n]存在平方数 ⌈ n ⌉ 2 \lceil \sqrt{n} \rceil^2 ⌈n⌉2。同理,我们可以证明,区间[n,2n]存在平方数 ⌈ 2 n ⌉ 2 \lceil \sqrt{2n} \rceil^2 ⌈2n⌉2
利用上述定理,我们可以构造所求序列。
对于数x,我们可以构造完全平方数
h
=
⌈
2
x
⌉
2
h=\lceil \sqrt{2x} \rceil^2
h=⌈2x⌉2。
讲解区间上[h-x,x]上的元素构造。
接着,再用同样的方式,递归构造,处理数h-x-1。
详见代码。
#include
using namespace std;
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 tc; cin >> tc;
while (tc--) {
cin >> n; recurse(n - 1);
for (int i = 0; i < n; i++)
cout << ans[i] << ' ';
cout << '\n';
}
}
觉得我文章还不错的话,weixin gongzhonghao搜 对方正在debug,关注下,一起快乐刷题吧~