HDU1518 DFS
传送门
题意就是好多棍子,看能不能拼成正方形。主要注意的有几点:- 所有棍子都要用到,不能剩余
- 输入已经保证大于4根棍子了。所以无需判断可能小于3根棍子的情况
- 棍长的总数首先要是4的倍数,才能进行。否则直接输出 “no”
- 当前面前提满足以后,再满足3 根棍子拼好,就完工了。最后一根一定能拼好。
bool dfs(int count,int pos,int res)这是本题中DFS算法的状态。三个要素 count (已经拼好的棍子个数),pos (现在遍历的第几根棍子),res (要凑成目标长度剩余的长度)
当然在输入数据以后要进行一次排序,从大到小排好依次遍历。
我们要定义一个全局的变量 goal 代表你要凑齐的目标长度,换句话说就是总长度的 1/4 。
goal = sum/4;标记的数组我们定义为used[21].值为 true 则标记过,即用过了。值为 false 则未用过。
//声明,全局
bool used[21];
//初始化为false,main函数中
memset(used,false,sizeof(used));下面看DFS函数的代码:
bool dfs(int count,int pos,int res)
{if(count==3)//3根拼好就能保证都拼好return true;for(int i=pos;i//1:如果标记过就跳过下面过程
//2:先标记好true
//3:如果第i根棍子的长度和你剩余的所需要的棍子的长度一样。那么这根棍子就拼好了 //4:由//3可知,又拼好了一根,所以递归下一个棍子要拼的状态,count+1。而pos初始化为0.从头开始便利,res变为goal,即下一根棍子剩余的长度是全部所需长度。
//5:如果第i根棍子的长度小于目前所需的。那么也把它加上 //6:下一个状态。count不变,因为这根还没拼好。pos = i+1,因为第i根已用。res-stick[i] 不言而喻了。 //7:前面如果满足的话,就会返回true。而不执行这一句//7这句。如果能走到//7这句,那么就是说前面的情况都不成功,也就是说这根棍子不能凑近去,所以要推翻加入这根棍子的方案
完整代码:
#include
#include
using namespace std;
bool used[21];
int stick[21];
int t,goal;
bool cmp(int a,int b)
{return a>b;
}
bool dfs(int count,int pos,int res)
{if(count==3)//3根拼好就能保证都拼好return true;for(int i=pos;i>n;while(n--){cin>>t;int sum=0;for(int i=0;i>stick[i];sum+=stick[i];}if(sum%4){printf("no\n");continue;}goal = sum/4;memset(used,false,sizeof(used));sort(stick,stick+t,cmp);if(dfs(0,0,goal))//初始态printf("yes\n");elseprintf("no\n");}return 0;
} 本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
