2026.1.17 作业 # P1118 [USACO06FEB] Backward Digit Sums G/S
题目描述
FJ 和他的奶牛们喜欢玩一个心算游戏。他们将数字从 \(1\) 到 \(N(1 \le N \le 12)\) 按某种顺序写下来,然后将相邻的数字相加,得到一个数字更少的新列表。他们重复这个过程,直到只剩下一个数字。例如,游戏的一种情况(当 \(N=4\) 时)可能是这样的:
3 1 2 44 3 67 916
在 FJ 背后,奶牛们开始玩一个更难的游戏,她们试图从最终的总和和数字 \(N\) 中确定起始序列。不幸的是,这个游戏有点超出了 FJ 的心算能力。
编写一个程序来帮助 FJ 玩这个游戏,并跟上奶牛们的步伐。
输入格式
共一行两个正整数 \(n,sum\)。
输出格式
输出包括一行,为字典序最小的那个答案。
当无解的时候,请什么也不输出。
输入输出样例 #1
输入 #1
4 16
输出 #1
3 1 2 4
说明/提示
- 对于 \(40\%\) 的数据,\(1\le N\le 7\);
- 对于 \(80\%\) 的数据,\(1\le N \le 10\);
- 对于 \(100\%\) 的数据,\(1\le N \le 12\),\(1\le sum\le 12345\)。
#include <bits/stdc++.h>
using namespace std;
int c[20][20],n,m,s[20];
int main() {c[0][0]=c[1][0]=c[1][1]=1;for (int i=2;i<15;i++){c[i][0]=c[i][i]=1;for (int j=1;j<i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];}scanf("%d%d",&n,&m);for (int i=0;i<n;i++) s[i]=i+1;do{int Ans=0;for (int i=0;i<n;i++) Ans+=s[i]*c[n-1][i];if (Ans==m) {cout<<s[0];for (int i=1;i<n;i++) cout<<" "<<s[i];cout<<endl;return 0;}}while(next_permutation(s,s+n));return 0;
}