uva:11129 - An antiarithmetic permutation(分治法)

题目:11129 - An antiarithmetic permutation


题目大意:求n的反算术级数。就是排序0 。。n - 1 要求不存在长度大于2的序列。例如:5的序列排列后(0, 5, 4, 3, 1, 2) ,但是(0,1,2)是一个等差序列,同样的还有(5,4,3), (5,3,1)...

解题思路:这题需要找到排列的策略:将整个序列分成差不多等长的两个部分,使得左右两部分各自成为等差数列,这样左边的数和右边的数组合就一定不会出现等差数列。然后把这个作为子问题,递归求解。递归到左右部分小于等于2可以了,因为它要求不出现长度为3以上的等差数列。


代码:

#include <stdio.h>

const int N = 10005;
int n;
//k等差 , t用来存放排列后的序列, 
void solve (int l, int r, int *t, int k) {
	

	if (r + 1 - l <= 2)  //长度不大于2就可以返回了
		return;
	int m =  l + (r - l) / 2;
	int temp = t[l + 1];
	for (int i = l, j = t[l]; i <= m; i++, j += k)
		t[i] = j;
	for (int i = m + 1, j = temp; i <= r; i++, j += k) 
		t[i] = j;
	solve (l, m, t, k * 2);
	solve (m + 1, r, t, k * 2);

}

int main () {

	while (scanf ("%d", &n), n) {

		int t[N];
		for (int i = 0; i < n; i++)
			t[i] = i;
		solve(0, n - 1, t, 2);
		printf ("%d:", n);
		for (int i = 0; i < n; i++)
			printf (" %d", t[i]);
		printf ("\n");
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值