您的位置:首页 > 其它

HDU 1258 Sum It Up

2015-07-25 11:33 435 查看
题目地址:点击打开链接

思路:好题,一步一步分析,把我错误的代码也贴上来,便于深入理解

错误代码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;
}


直接回溯,有多次重复输出,原来是要判断递归的起点是否相同,不同才继续DFS否则会重复输出
错误代码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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: