CF1713C Build Permutation--构造算法确实难

题意:

给定n,从0开始编号,也即(0--n-1),是否有这样的一个排列p(元素为0-n-1,每个元素出现一次),使得pj+i是平方数

解:

由于下标i是固定的,不妨按照递增i来分析

n=7:

0,1,2,3,4,5,6

1,0,2, 6,5,4,3

n=8:

0,1,2,3,4,5,6,7

1,0,7,6,5,4,3,2

n=9:

0,1,2,3,4,5,6,7,8

0,8,7,6,5,4,3,2,1

我们可以发现,对于一定的区间,这个平方数是一样的

对于一样的平方数,我们确定这个区间左右端点,l,r,也就是l+r是一个平方数

那么p[l]=r,p[r]=l.

我们是知道右端点的,最开始r=n-1

对于r,确定x>=n时,最小的平方数x。

codeforces上给了一个结论是:必然能在n-2n之间找到一个平方数x,且为s=pow(floor(sqrt(2*r)),2)

那么左端点即为s-r(l+r==s)

再递归地解决l-1的情况,直到参数<0

#include<iostream>
#include<array>
#include<cmath>
using namespace std;
const int maxn=1e5+1e1;
array<int,maxn>a;
void rec(int r)
{
    if(r<0)return;
    int s=sqrt(2*r);s*=s;
    int l=s-r;rec(l-1);
    for(;l<=r;l++,r--)
    {
        a[l]=r;a[r]=l;//l+r==平方数
    }
}
int main()
{
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        rec(n-1);
        for(int i=0;i<n;i++){cout<<a[i]<<" ";}cout<<"\n";
    }
    return 0;
}

 

posted @ 2022-09-13 16:56  惣聪术  阅读(74)  评论(0)    收藏  举报