题意:给出n个正整数,x[1..n],对于给定的t(t < 1000),找出所有满足和为t的x的组合。降序输出。
其实这题较为简单,属于搜索题。将x排序后搜索即可。最后输出时去重需要动动脑筋。我将结果保存在了一棵树中。每次找到符合的结果时,将其加入树中。最后输出答案时,从叶子节点往回遍历,可得不重复的所有解。
代码如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <string>
using namespace std;
const int maxn = 20;
int a[maxn], vis[maxn], b[maxn];
int n, t;
int flag;
struct node {
int v, cnt;
struct node * parent;
struct node * child[maxn];
};
struct node *root = (node *)malloc(sizeof(node));
bool cmp(int x, int y) { return x > y; }
node* add_node(node* u, int val) {
u->child[u->cnt] = (node *)malloc(sizeof(node));
u->child[u->cnt]->parent = u;
u->child[u->cnt]->v = val;
u->child[u->cnt]->cnt = 0;
u->cnt++;
return u->child[u->cnt - 1];
}
int f(node *u, int x) {
int len = u->cnt;
for (int i = 0; i < len; i++)
if (u->child[i]->v == x)
return i;
return -1;
}
void add_sum(int x[maxn], int num) {
int i = 1;
node * p = root;
int t = f(p, x[i]);
while (t != -1) {
p = p->child[t];
i++;
t = f(p, x[i]);
}
while (i <= num) {
p = add_node(p, x[i]);
i++;
}
}
void dfs(int u, int sum, int cnt) {
if (sum > t) return;
b[cnt] = a[u];
if (sum == t) {
flag = 1;
add_sum(b, cnt);
// for (int i = 1; i <= cnt; i++) printf("%d%c", b[i], " \n"[i == cnt]);
return;
}
for (int i = u; i <= n; i++) if (!vis[i] && sum + a[i] <= t) {
vis[i] = 1;
dfs(i, sum + a[i], cnt + 1);
vis[i] = 0;
}
}
void print(node *u) {
// printf("node:%d %d\n", u->v, u->cnt);
if (u->parent != root) {
print(u->parent);
printf("+%d", u->v);
}
else printf("%d", u->v);
}
void Dfs(node *u) {
int len = u->cnt;
if (len == 0) { print(u); puts(""); return; }
for (int i = 0; i < len; i++) {
Dfs(u->child[i]);
}
}
int main() {
while (~scanf("%d%d", &t, &n) && t) {
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
printf("Sums of %d:\n", t);
sort(a + 1, a + n + 1, cmp);
root->cnt = 0;
flag = 0;
for (int i = 1; i <= n; i++) {
memset(vis, 0, sizeof(vis));
vis[i] = 1;
dfs(i, a[i], 1);
}
if (!flag) { puts("NONE"); continue; }
int len = root->cnt;
for (int i = 0; i < len; i++) {
Dfs(root->child[i]);
}
}
return 0;
}