You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
typedef short int int16; //使用短整型,以防止MLE
|
|
|
|
|
const int N = 110; //数组上限
|
|
|
|
|
const int M = 100; //极限值n的上限
|
|
|
|
|
|
|
|
|
|
int n; //输出以数字n结尾的加法链
|
|
|
|
|
int cnt; //已经完成预处理的数字个数,当n=M时,表示所有范围内的数字均已成功生成加法链
|
|
|
|
|
|
|
|
|
|
queue<vector<int16>> q; //以动态数组记录状态
|
|
|
|
|
vector<int16> ans[N]; //二维数组,第一维记录是哪个数,第二维是一个动态数组,描述第一维的数是怎么构建的加法链路径
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
// 一、预处理出M以内的所有 加成序列
|
|
|
|
|
// bfs
|
|
|
|
|
q.push({1}); //从{1} 出发宽搜
|
|
|
|
|
while (q.size()) {
|
|
|
|
|
auto a = q.front();
|
|
|
|
|
q.pop();
|
|
|
|
|
|
|
|
|
|
int16 v = a[a.size() - 1]; //最后一位的填充值
|
|
|
|
|
|
|
|
|
|
// 如果没有计算过,那么现在是第一次到达,最短路径,记录已计算过
|
|
|
|
|
// 并且,记录 ans[v]的最短路径就是a这个动态数组
|
|
|
|
|
if (!ans[v].size()) ans[v] = a, cnt++; // cnt++ :v这个数计算完成,数量++
|
|
|
|
|
|
|
|
|
|
//从数组状态a开始扩展,下面的办法就统一扩展了一位,然后后面的循环中,都使用这一位
|
|
|
|
|
vector<int16> x = a;
|
|
|
|
|
x.emplace_back(0); // emplace_back()是c++11的新特性,可以理解为push_back的加强版本
|
|
|
|
|
|
|
|
|
|
for (int i = a.size() - 1; i >= 0; i--) {
|
|
|
|
|
int16 s = v + a[i]; // a[n]肯定由a[n-1]+?得到
|
|
|
|
|
if (s > M) continue; // 冒了肯定没用
|
|
|
|
|
x[a.size()] = s; // 构建新状态
|
|
|
|
|
q.push(x); // 入队列等待扩展
|
|
|
|
|
}
|
|
|
|
|
//已经计算完M个,可以结束了
|
|
|
|
|
if (cnt == M) break;
|
|
|
|
|
}
|
|
|
|
|
// 二、输入n 后查表
|
|
|
|
|
while (scanf("%d", &n) && n) {
|
|
|
|
|
for (int i : ans[n]) printf("%d ", i);
|
|
|
|
|
puts("");
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|