原题目如下:
FJ 和 他的奶牛们在玩一个心理游戏。他们以某种方式写下1至N的数字(1<=N<=10)。 然后把相邻的数相加的到新的一行数。重复这一操作直至只剩一个数字。比如下面是N=4时的一种例子
3 1 2 4
4 3 6
7 9
16
在FJ回来之前,奶牛们开始了一个更难的游戏:他们尝试根据最后结果找到开始的序列。这已超过了FJ的思考极限。
写一个程序来帮助FJ吧
Line 1: 两个空格分开的整数:N与最后的和
Output
Line 1: 满足要求的1~N的一个排列。若有多种情况,输出字典序最小的一种
4 16
Sample Output
3 1 2 4
Hint
样例解释:
这里还有其他可能的排列,如 3 2 1 4,但 3 1 2 4 是字典序最小的
解题思路:
这道题还是一个全排列的问题,直接用next_permutation()函数就好了,并且这道题输出的是字典序最小的排列。所以,我们直接选择用next_permutation()函数来按照从小到大字典序生成排列。生成排列进行循环时,对每个排列进行相加最后取得结果跟输入的结果相比较就好了。(如果成功则输出该排列退出循环,不成功就跳过)
这道题我以为按照这个思想做会TLE,但是没有。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, sum; //代表输入的数字个数和最终的和
int arr[10]; //代表装入数字的数组
int arr1[10];
void solve(); //代表进行计算的函数
void solve()
{
int i, j;
for (i = 1; i <= n; i++)
{
arr[i - 1] = i; //给arr数组赋初始序列
}
do
{
for (i = 1; i <= n; i++)
{
arr1[i - 1] = arr[i-1]; //给arr1数组赋arr数组相同的值
}
for (i = 1; i <= n; i++) //代表进行循环的次数
{
for (j = 0; j < n - i; j++) //代表每个序列中的数进行相加的次数
{
arr1[j] = arr1[j] + arr1[j + 1];
}
}
if (arr1[0] == sum)
{
for (i = 0; i < n; i++)
{
if (i == 0)
{
printf("%d", arr[i]);
}
else
{
printf(" %d", arr[i]);
}
}
printf("\n");
break;
}
} while (next_permutation(arr, arr + n));
}
int main()
{
int i;
while (scanf("%d %d", &n, &sum) != EOF)
{
solve();
}
return 0;
}