问题描述:
设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。输入数据第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值。接下来的1行中,有n个正整数,表示集合S中的元素。 是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。将子集和问题的解输出。当问题无解时,输出“No Solution!”。
输入:
5
3 9 1 8 2
-1
输出
No Solution!
输入:
5
3 9 1 8 2
10
输出
9 1
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//集合中元素的个数
int n;
//要求的和
int sum;
//标记集合中被选中元素的索引
int flag[100];
//记录找到结果数,为0表示无解
int result = 0;
int temp = 0;
//要输入的集合
int set[100];
void findPass(int i) {
if (i > n) {
return;
}
else {
temp += set[i];
flag[i] = 1;
if (sum == temp) {
for(int j = 0; j < n; j++) {
if(flag[j] == 1) {
printf("%d ", set[j]);
}
}
printf("\n");
result++;
exit(0);
}else if (temp < sum)
{
findPass(i+1);
}else{
temp -= set[i];
flag[i] = 0;
findPass(i+1);
return;
}
}
}
int main(void) {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &set[i]);
}
scanf("%d", &sum);
for(int i = 0; i < n; i++) {
memset(flag, 0, sizeof(flag));
temp = 0;
findPass(i);
}
if (result == 0) {
printf("No Solution!\n");
}
return 0;
}