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 length bigger than 2, i.e. there are no three indices 0 ≤ i < j < k < n such that (pi,
pj, pk) forms an arithmetic progression.

For example, the sequence (2, 0, 1, 4, 3) is an antiarithmetic permutation of 5. The sequence (0, 5, 4, 3, 1, 2) is not an antiarithmetic permutation of 6 as its first, fifth and sixth term (0, 1, 2) form an arithmetic progression; and so do its second,
fourth and fifth term (5, 3, 1).

Your task is to generate an antiarithmetic permutation of n.

Each line of the input file contains a natural number 3 ≤ n ≤ 10000. The last line of input contains 0 marking the end of input. For each
n from input, produce one line of output containing an (any will do) antiarithmetic permutation of
n in the format shown below.

Sample input

3
5
6
0

Output for sample input

3: 0 2 1
5: 2 0 1 4 3
6: 2 4 3 5 0 1

题目大意:给定一个数n, 求一个0~n-1组成的序列,使得其中同向的升序或降序不为等差数列。

解题思路:利用递归,每次都将奇数序号的数和偶数序号的数分开再合并(放在两边),地轨道最后就是答案。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int num[10005], A[10005], B[10005];
void solve(int a, int b) {
	if (a == b) {
		return;
	}
	int temp = a, cnt1 = 0, cnt2 = 0;
	for (int i = a; i <= b; i += 2) {
		A[cnt1++] = num[i];
	}
	for (int i = a + 1; i <= b; i += 2) {
		B[cnt2++] = num[i];
	}
	for (int i = 0; i < cnt1; i++) {
		num[temp++] = A[i];
	}
	for (int i = 0; i < cnt2; i++) {
		num[temp++] = B[i];
	}
	solve(a, a + cnt1 - 1);
	solve(a + cnt1, a + cnt1 + cnt2 - 1);
}
int main() {
	int n;
	while (scanf("%d", &n), n) {
		for (int i = 0; i < n; i++) {
			num[i] = i;
		}
		solve(0, n - 1);
			printf("%d:", n);
		for (int i = 0; i < n; i++) {
			printf(" %d", num[i]);
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-10-02 08:19:14

uva 11129 An antiarithmetic permutation (递归)的相关文章

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)... 解题思路:这题需要找到排列的策略:将整个序列分成差不多等长的两个部分,使得左右两部分各自成为等差数列,这样左边的数和右边的数组合就一定不会出现等差数列.然后把这个作为子问题,递归求解.递归到

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 12627 - Erratic Expansion(递归求解)

递归的边界条件写的多了--没必要写呢么多的.. 不明白可共同探讨~ #include<cstdio> #include<iostream> #include<cmath> using namespace std; long long dp(int kk,int pos) { int n=kk;int temp=(int)pow(2,n); // printf("%d %d\n",kk,pos); if(kk==0&&pos==1) r

(白书训练计划)UVa 12627 Erratic Expansion(递归+找规律)

题目地址:UVa 12627 这题是先找规律,规律在于对于第k个小时的来说,总是可以分成右下角全是蓝色气球,右上角,左下角与左上角三个一模一样的k-1个小时的气球.这样的话,规律就很清晰了,然后用递归做比较方便... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <ma

uva 10795 A Different Task(递归模拟)

uva 10795 A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefly the problem is to transfer all the disks from peg-A to peg-C using peg-B as intermediate one in such a way that at no stage a larger disk

Uva 12627 Erratic Expansion(递归)

这道题大体意思是利用一种递归规则生成不同的气球,问在某两行之间有多少个红气球. 我拿到这个题,一开始想的是递归求解,但在如何递归求解的思路上我的方法是错误的.在研读了例题上给出的提示后豁然开朗(顺便吐槽一下算法竞赛第二版在这这道题目上(P246)提示写的有问题,g(k,i)=2g(k-1,i-2^(k-1))+c(k-1)  ,他把c(k-1)写成了c(k)...我纠结这个纠结了好久) 根据题目提示,这道题可以用f(k,i)表示k小时后最上边i行的红气球总数 那么我们的答案就可以表示为f(k,b

UVA 839 Not so Mobile (递归建树 判断)

#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<string> #include<math.h> #include<stack> #include<cstdlib> #include<algorithm> #include<cctype> #include<sstream&

UVA 247 图论 floyd算法+递归遍历

先用floyd求出传递闭包,构造出一个新图,然后用递归的方法遍历图输出相互联通的节点. #include<iostream> #include<string> #include<algorithm> #include<map> #include<cstring> #include<vector> #include<cstdio> using namespace std; #define N 500 int d[N][N];

UVa 699 The Falling Leaves(递归建树)

题意  假设一棵二叉树也会落叶  而且叶子只会垂直下落   每个节点保存的值为那个节点上的叶子数   求所有叶子全部下落后   地面从左到右每堆有多少片叶子 和上一题有点像  都是递归输入的  一个节点(设水平位置为p)  则它的左右儿子节点的水平位置分别为  p-1  p+1   也是可以边输入边处理的  输入完也就得到答案了   注意每个样例后面都有一个空行  包括最后一个 #include<cstdio> #include<cstring> using namespace s