[遞歸]UVA11129 An antiarithmetic permutation

Problem A: 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 < nsuch that (pipjpk) 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 eachn 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

W. Guzicki, adapted by P. Rudnicki

一開始題目就理解錯了,各種WA,後來參考網上的大神的思路。。

題意:給定一個包含了0到n - 1的序列。。要使得這個序列中每個長度大於2的子序列都不是等差數列。。

思路:對於一個等差的序列。如0 1 2 3 4 5 我們可以這樣做,把他分離成2部分等差子序列0 2 4和1 3 5然後組合成一個新的序列0 2 4 1 3 5。這樣做的話,可以保證前半部分無法和後半部分組合成等差數列。可以證明,一個序列的等差是k,首項爲a1,序列爲,a1, a1 +k, a1 + 2k, a1 + 3k .... a1 + (n - 1)k.分成的兩部分爲a1, a1 + 2k , a1 + 4k ....、 a1, a1 + k, a1 + 3k, a1 + 5k...如此一來,任意拿前面和後面組成序列的話。後面和後面的差都是2k的倍數,前面和後面的都是2k + 1的倍數。這樣是成不了等差的。。 如此一來。我們只要把序列一直變換,變換到個數小於等於2即可。

#include<iostream>
#include<cstring>

using namespace std;

int arry[10005],bin[10005];
int n;

void solve(int l,int r)
{
	if(r==l) return;
	memcpy(bin,arry,sizeof(arry));
	int k=l;
	for(int i=l;i<=r;i+=2,k++)
		arry[k]=bin[i];
	for(int i=l+1;i<=r;i+=2,k++)
		arry[k]=bin[i];
	solve(l,(l+r)/2);
	solve((l+r)/2+1,r);
}

int main()
{
	while(cin>>n&&n)
		{
			int i;
			for(i=0;i<n;i++)
				arry[i]=i;
			solve(0,n-1);
			cout<<n<<":";
			for(i=0;i<n;i++)
				cout<<" "<<arry[i];
			cout<<endl;
		}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章