蓝桥杯 算法训练 数字游戏
题目描述
- 资源限制
时间限制:1.0s 内存限制:256.0MB
- 问题描述
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解(题目错误,无解不输出)。
- 输入格式
第1行为两个正整数n,sum
- 输出格式
一个1~N的一个排列
- 样例输入
4 16
- 样例输出
3 1 2 4
- 数据规模和约定
0<n<=10
方案1 递归版本
#include<iostream>
using namespace std;
int n, sum;
int ans[10];
bool flag[10];
bool isTrue(int ans[], int n, int sum){
int temp[n];
for(int i=0; i<n; i++){
temp[i]=ans[i];
}
for(int i=1; i<n; i++){
for(int j=0; j<n-i; j++){
temp[j] = temp[j] + temp[j+1];
}
}
return temp[0] == sum;
}
bool f(int i, int n, int ans[], bool flag[], int sum){
if(i==n){
return isTrue(ans, n, sum);
}
for(int ii=0; ii<n; ii++){
if(flag[ii]==false){
ans[i] = ii+1;
flag[ii]=true;
if(f(i+1, n, ans, flag, sum)){
return 1;
}
flag[ii]=false;
}
}
return 0;
}
int main(){
cin>>n>>sum;
if(f(0, n, ans, flag, sum)){
for(int i=0; i<n; i++){
cout<<ans[i]<<" ";
}
}else{
return 0;
}
}