input:
3
3
4
7
output:
1 0 2
0 3 2 1
1 0 2 6 5 4 3
题目大意:给我们一个数n,让我们找出一个0~n-1的全排列,a[0]~a[n-1],0<=a[i]<n,并且每个数都满足a[i]+i为某个数的平方,让我们输出这个排列,如果不存在输出-1。
解题思路:首先我们要知道一个定理,对于一个数字n,区间[n,2n]中一定存在一个平方数,然后我们从后往前看,对于第x1个数,我们找到比它大的最小的一个平方数s,令x2=s-x1,那么我们就只需要将从x2到x1这段数字颠倒即可,这里根据我们之前给出的定理可以知道x2<=x1,处理完一段后再处理前面,这样我们其实可以发现,对于任意一个n,我们都可以找到一个0~n-1的排列使其满足条件。
上代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int N=1e5+10;
int a[N];
int t,n;
int main()
{
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
a[i]=i;
int last=n-1;
vector<pair<int,int>>temp;
while(last>=0)
{
int s=ceil(sqrt((double)last));
s=s*s;
int pre=s-last;
temp.push_back({pre,last});
last=pre-1;
}
for(auto p:temp)
{
int l=p.first,r=p.second;
for(int i=l;i<=r;i++)
a[i]=l+r-i;
}
for(int i=0;i<n;i++)
{
cout<<a[i];
if(i==n-1)
cout<<endl;
else
cout<<" ";
}
}
return 0;
}