问题描述
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。
解答:
首先这题需要有一个全排列的想法,因为这样的活就可以定义一个自然序列当然是需要有序的,比如是1,2,3,4,········ ,然后每一轮去使用当前这个序列执行相邻相加看看最后是否等于sum,如果不等,打乱当前序列继续上面步骤:具体需要导入的包看这篇文章:http://t.csdn.cn/EXWCW
具体实现代码如下;
#include
#include
const int N =10;
using namespace std;
int main(){
int n ,sum;
cin>>n>>sum;
int* a = new int[n+1];
int b[N];
int j;//use to count the add num times;
for(int i = 1;i<n+1;i++){
a[i] = i;
}
do{
for(int i = 1;i<n+1;i++){
b[i] = a[i];}
j = n+1;
while(j>1){
for(int i = 1;i<j-1;i++) //这里需要注意使用i<j-1 而不能是i<n 我也不知为啥有大佬可以指点下
{ b[i] =b[i] +b[i+1];}
j--;
}
if(b[1]==sum){
for(int i =1 ;i<n+1;i++)
{cout<<a[i]<<" ";}
break;
}
}while(next_permutation(a+1,a+n+1));
}