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;
}
思路:好题,一步一步分析,把我错误的代码也贴上来,便于深入理解
错误代码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;
}
相关文章推荐
- 根据像素画圆
- hdoj.5289 Assignment【单调队列】 2015/07/25
- A计划(bfs)
- 去掉标题栏、信息栏和实现全屏
- sublime常用快捷键
- Linux下的网络配置命令
- MPlayer-ww 增加边看边剪切功能+生成高质量GIF功能
- Java Servlet与Applet、CGI、JSP的比较
- 1019. General Palindromic Number (20)
- nyoj-20-吝啬的国度(深搜)
- 开机自动开启小键盘灯
- WPS 文字排版 标题回车后标题号自动增加
- css的作业
- 在netbean里面无法启动tomcat
- nyoj91 阶乘之和
- 查询区间内不同数字的个数 lydsy1878
- 新浪微博,腾讯微博mysql数据库主表猜想
- 关于cocos2dx如何通过jni进行c++与java的交互
- cocos2dx Android签名总结
- Android train--一些小技能