题面
题意
给出一个长度为n且无相同整数的序列,求该序列的一个排列使两序列中任意几个(大于0小于n)位置的数之和不相同.
方法
开始看到n<=22以为用状压,但无论是时间还是空间都很紧张,且n的范围纯属是因为评测时判断正确与否的复杂度为2^n.
正确方法是使除了最小数外,所有数都变成比它在序列中小一点的数,最小数变成最大数.
证明
假设不取最小值,那么和一定要比原来的序列小,因而不取的那一部分之和比原来的序列要大,故可以证明所有情况都不相等.
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int n,num[30],ans[30];
map<int,int>id;
int main()
{
register int i,j;
cin>>n;
for(i=1;i<=n;++i)
{
scanf("%d",&num[i]);
id[num[i]]=i;
}
sort(num+1,num+n+1);
for(i=2;i<=n;++i)
{
ans[id[num[i-1]]]=num[i];
}
for(i=1;i<=n;++i)
{
ans[i]?printf("%d ",ans[i]):printf("%d ",num[1]);
}
}