codeforces 构造 Build Permutation

题目描述:

 题目大意:生成一个排列,使得 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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值