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;
}

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

时间: 2024-10-13 14:41:57

uva:11129 - An antiarithmetic permutation(分治法)的相关文章

uva 11129 An antiarithmetic permutation (递归)

uva 11129 An antiarithmetic permutation A permutation of n+1 is a bijective function of the initial n+1 natural numbers: 0, 1, ... n. A permutation p is called antiarithmetic if there is no subsequence of it forming an arithmetic progression of lengt

UVA, 11129 An antiarithmetic permutation

题意:读入一个数n,代表从0到n-1的数列,让你输出一个数列,这个数列的子序列均不为等差数列 思路:= =参考了网上大神的代码,得到的一个规律:将等差(?)数列按奇偶位置分成两个数列,再重复这一步骤,最后得到的数列一定是非等差数列,其实就是分治法 ps:分治法:将大的问题分为无数个小问题,解决后再将得到的解合并,得到大问题的答案 例:0 1 2 3 4 5 6 7 ->(0 2 4 8)(1 3 5 7) 此刻我们得到了两个小等差数列,但此时数列已不是等差数列了 ->(0 4)(2 8)(1

UVA - 1608 Non-boring sequences(分治法)

题目: 如果一个序列的任意连续的子序列中至少有一个只出现一次的元素,则称这个序列是不无聊的.输入一个n(n≤200000)个元素的序列A(各个元素均为109以内的非负整数),判断它是不是不无聊的. 思路: 分治法,平常确实用的非常的少,这次借这个题目熟悉一下.代码思路是学习的紫书上的代码的. 在[L,R]范围内枚举是唯一的数,从这个数的左右两边开始判断是不是左右两边的序列都符合唯一性条件.(包含这个唯一数的区间都是符合条件的,所以只要在从两边开始枚举就可以了.) 代码: #include <bi

UVA 11582 - Colossal Fibonacci Numbers!(数论)(分治法幂取模)

巨大的斐波那契数! 题目大意:斐波那契数列f[N],给你a,b,n,求f[a^b]%n. 思路:数论题.f[a^b]%n是有周期的,我们求出来这个周期后就可以将简化成f[(a%周期)^b]%周期运用分治法幂取模. 注意用unsigned long long(貌似是 long long的二倍),不然会溢出,又学了一招... 不知道哪的bug,一直改不对,一直,后来捡来别人的和自己一样的代码一改就对了,,, #include<iostream>//UVA #include<cstdio>

经典算法学习之分治法(以排列、组合程序为例)

分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治法在每层递归是遵循的三个步骤: (1)分解原问题为若干个子问题,这些子问题是原问题的规模较小的实例. (2)解决这些子问题,队规的求解各个子问题,当子问题规模足够小的时候,直接求解. (3)合并这些子问题的解构成原问题的解. 显然归并排序是一个非常经典规矩的分治法的例子,鉴于之前已经写过一篇关于归并排序的博文,这里不在使用归并排序作为例子. 注意分治法的每一层递归

专题:分治法

分治法(Divide and Conquer) 作为五大算法之一的分治法,可算是最早接触的一种算法.分治法,与其说是一种算法,不如将其称为策略来的更贴切一些.算法的思想就是将大问题分成小问题,并解决小问题之后合并起来生成大问题的解. 分治法的精髓: 分--将问题分解为规模更小的子问题: 治--将这些规模更小的子问题逐个击破: 合--将已解决的子问题合并,最终得出“母”问题的解: 分治法的作用,自然是让程序更加快速地处理问题.比如一个n的问题分解成两个n/2的问题,并由两个人来完成,效率就会快一些

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

分治法

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同.递归的解这些子问题,然后将各子问题的解合并得到原问题的解. 分治法所能解决的问题一般具有以下几个特征: 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质. 3) 利用该问题分解出的子问题的解可以合并为该问题的解: 4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题. 分治法的基本步骤:分治法在

算法实验:分治法合并排序(C++)

这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来. 我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别.但是下面的报告是我放到vs里面测试过的,可以直接用,不影响. 第一部分:(解析) 题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组. 题目分析: 需要随机产生一个整数数组: 采用的算法是合并排序,也就是用归并排序: 输出排序后的数组. 随机产生一个整数数组:这个问题首先想到的是用rand()函