题解:CF2071B Perfecto
简述题意
判断是否存在一个排列:
- 长度为
n ; -
存在则输出。
算法分析
很容易判断无解:如果
接下来判断如何输出一个解。
首先
所以先构造
很显然,当前不为一个正解。
我们发现,前
那么前
因为令
显然
这样我们就找到了一个方案使得有解。
代码实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[114514*10],sum[114514*10];
signed main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
if((n+1)*n/2==(int)sqrt((n+1)*n/2)*(int)sqrt((n+1)*n/2)) cout<<"-1\n";
else
{
for(int i=1;i<=n;i++) a[i]=i;
for(int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+a[i];
if(sum[i]==(int)sqrt(sum[i])*(int)sqrt(sum[i])) swap(a[i],a[i+1]);
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<'\n';
}
}
return 0;
}