题目地址:点击打开链接
思路:好题,一步一步分析,把我错误的代码也贴上来,便于深入理解
错误代码1:
#include<stdio.h> #include<string.h> int t,visit[15],n,a[15]; void dfs(int l) { int i,flag = 1; if(l > t) return; else if(l == t) { for(i=0; i<n; i++) { if(visit[i]) { if(flag) { printf("%d",a[i]); flag = 0; } else printf("+%d",a[i]); } } printf("\n"); } else { for(i=0; i<n; i++) { if(!visit[i]) { visit[i] = 1; l += a[i]; dfs(l); l -= a[i]; visit[i] = 0; } //l -= a[i]; //visit[i] = 0;要放在里面,别乱搞 } } } int main() { int i,sum; while(scanf("%d%d",&t,&n) != EOF) { memset(visit,0,sizeof(visit)); sum = 0; for(i=0; i<n; i++) { scanf("%d",&a[i]); sum += a[i]; } if(sum < t) printf("NONE\n"); else dfs(0); } return 0; }
错误代码2:
#include<stdio.h> #include<string.h> int t,visit[15],n,a[15]; void dfs(int l) { int i,flag = 1,last = -1; if(l > t) return; else if(l == t) { for(i=0; i<n; i++) { if(visit[i]) { if(flag) { printf("%d",a[i]); flag = 0; } else printf("+%d",a[i]); } } printf("\n"); } else { for(i=0; i<n; i++) { if(!visit[i] && a[i] != last) { last = a[i]; visit[i] = 1; l += a[i]; dfs(l); l -= a[i]; visit[i] = 0; } //l -= a[i]; //visit[i] = 0;要放在里面,别乱搞 } } } int main() { int i,sum; while(scanf("%d%d",&t,&n) != EOF) { memset(visit,0,sizeof(visit)); sum = 0; for(i=0; i<n; i++) { scanf("%d",&a[i]); sum += a[i]; } if(sum < t) printf("NONE\n"); else dfs(0); } return 0; }
递归起点已经不同了啊,为啥还有重复输出呢?递归起点是1和递归起点是3的时候输出结果都是3+1,必须要保证下一次递归的起点比这次低,才不会有重复输出
AC代码:
#include<stdio.h> #include<string.h> int t,visit[15],n,a[15],flag2; void dfs(int l,int start)//只能是起点以后的数搞,不然大的输出一次,小的输出一次,起点以后搞就能保证只输出一次 { int i,flag = 1,last = -1; if(l > t) return; else if(l == t) { flag2 = 1; for(i=0; i<n; i++) { if(visit[i]) { if(flag) { printf("%d",a[i]); flag = 0; } else printf("+%d",a[i]); } } printf("\n"); } else { for(i=start; i<n; i++) { if(!visit[i] && a[i] != last) { last = a[i]; visit[i] = 1; l += a[i]; dfs(l,i+1); l -= a[i]; visit[i] = 0; } } } } int main() { int i,sum; while(scanf("%d%d",&t,&n)) { if(n == 0)//要注意结束条件啊 break; flag2 = 0; memset(visit,0,sizeof(visit)); sum = 0; for(i=0; i<n; i++) { scanf("%d",&a[i]); sum += a[i]; } printf("Sums of %d:\n",t); dfs(0,0); if(flag2 == 0) printf("NONE\n"); } return 0; }