题目描述
题意是给你一个N(1<=N<=10)
要求将1到N的数字进行排列 然后进行杨辉三角运算
每行的数字等于上一行相同坐标和上一行相同坐标右边的两个数字之和
最后得到唯一的一个数字
现在给予N 和一个M
请问初始的N个数字该如何排列才能得到这个M
输入
n m
n为数字个数 m为要求的最后的杨辉三角的和
输出
一行数字使用空格隔开
为初始的N个数字的排列 如果有多个答案 输出字典序最小的一个
样例
Sample Input
4 16
Sample Output
3 1 2 4 (3 2 1 4 也是答案 但是它不是字典序最小的排列)
算法1
解答
首先按照字典序DFS排列 N个数字,然后得到该排列最后的杨辉三角的顶端的数字 与输入的m比对,寻找答案
也可以使用杨辉三角的公式直接计算出最后的和 与m进行比较,这里采取的是暴力模拟计算杨辉三角的顶端数字
C++ 代码
#include <iostream>
using namespace std;
/*
Sample Input
4 16
Sample Output
3 1 2 4
*/
const int N = 15;
int arr[N];
int used[N];
int n, m;
int check[N][N];
//暴力模拟杨辉三角的记录
bool CheckArr() {
for (int i = 0; i < n; i++) {
check[0][i] = arr[i];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < n - i; j++) {
check[i][j] = check[i - 1][j] + check[i - 1][j + 1];
}
}
if (check[n - 1][0] == m) return true;
return false;
}
bool dfs(int idx)
{
if (idx >= n) {
if (CheckArr() == true) {
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
return true;
}
return false;
}
for (int i = 1; i <= n; i++) {
if (used[i] == 0) {
used[i] = 1; arr[idx] = i;
if (true == dfs(idx + 1)) return true;
used[i] = 0;
}
}
return false;
}
int main()
{
cin >> n >> m;
dfs(0);
return 0;
}