不要丧呀&&POJ 2362 && [剪枝]&&[dfs]
2018-02-04 20:21
211 查看
正方形这个题
理解题意还是比较重要的,对于这些小木棍,【正好】组成正方形
【正好】边长*4
并且不能切割,所以只是加来加去,判断组合方式
(可以重复)
【剪枝】
:
这个思想有点重要”
1.如果最长的比边长大放弃(因为不能切割)
2.如果sum总长/4 不是整数 也切去
***用%4 看
3,都满足的话,其实前三块边长构造好了直接退出-再简化了计算
(第四个也是这样,就emm)
其他需要注意的...大概写一下伪代码就是
读入n,
判断两个剪枝
dfs(array,vis,0,0,0)
(array,vis,num,len+array[i],i/s)
传进的存储的这个数组/是否进行了访问
后面的是:已经租好了几个(num)
已经存好了的长度
从第几个开始继续往后找
dfs内部:
判断num==3
for循环,这么多里面
没有到visit的
若相加<,标记,继续dfs
若相加等于,标记,继续dfs num+1
若都不是,取消标记,继续下一个for循环里的i
最后注意一下,如果用过了(continue而不是return)
if (vist[i])
continue;
以及什么时候返回true或者是false,总不能for都完了还没找到匹配的-你false去吧。
代码实现
#include<iostream>
#include<algorithm>
using namespace std;
int cmp(const void* a, const void* b) //降序
{
return *(int*)b - *(int*)a;
}
int n; //木棒数量
int side; //正方形边长
bool dfs(int* stick, bool* vist, int num, int len, int s) //num:已组合的正方形的边数 len:当前组合的边已组合的长度,len<=side
{ //s:stick[]的搜索起点
if (num == 3) //剪枝3,当满足剪枝1和2的要求时,只需组合3条side,剩下的棒子必然能够组成最后一条side
return true;
for (int i = s; i<n; i++)
{
if (vist[i])
continue;
vist[i] = true;
if (len + stick[i]<side)
{
if (dfs(stick, vist, num, len + stick[i], i)) //继续构建当前side
return true;
}
else if (len + stick[i] == side)
{
if (dfs(stick, vist, num + 1, 0, 0)) //构建新side
return true;
}
vist[i] = false;
}
return false;
}
int main(void)
{
int time;
cin>> time;
for (int t = 0; t<time; t++)
{
int sum = 0; //所有木棒长度之和
cin >> n;
int* stick = new int
;
bool* vist = new bool
;
for (int i = 0; i<n; i++)
{
cin >> stick[i];
vist[i] = false;
sum += stick[i];
}
if (n<4 || sum % 4 != 0) //剪枝1,不能构成正方形
{
cout << "no" << endl;
continue;
}
qsort(stick, n, sizeof(int), cmp); //降序排列,先组合长棒,因为长棒相对于短棒的组合灵活性较低
side = sum / 4; //边长
if (side<stick[0]) //剪枝2,side<max_stick
{
cout << "no" << endl;
continue;
}
if (dfs(stick, vist, 0, 0, 0))
cout << "yes" << endl;
else
cout << "no" << endl;
delete stick;
delete vist;
}
return 0;
}
感谢来源http://blog.csdn.net/lyy289065406/article/details/6647955
//另有个帖子说其实不排序也可以,大概排序了剪枝方便一点...什么的哎呀不管了
【其实有很多事情只要花一点点功夫或者是小改变,,,效果会特别惊人= =】
】
【笑cry:可能下次,这个治疗丧的办法就不管用了】
=========题外话============
(如果你把粘贴的代码拿走了之后还看到这里,那么谢谢你呀!)
【我平时运动的太少啦!!!!!!!如果可以去操场跑圈儿啊,我都要生锈啦】]
"其实你是 一幅画 狠狠地往人心上挂
其实想想我可能也会经常丧....只不过很多事情我都不去想而已= =
并且不去想的太多了,以及有什么是什么,根本不考虑后果
结果回来之后又丧又拖延又吃东西,六点半才去洗澡....
结果复活了啊啊啊啊啊啊啊本来还在咒骂怎么洗个澡都冷得 不行
原来大概是我温度太低了... 手感和身上的感觉不一样啊
温度上去之后出来就不冷了....真的好舒服啊(((
记得她之前跟我讲过,北方人不会明白,南方人的热水澡,热气便从头浇到脚的感觉 热气从内向外散发 而且我的沐浴露又超级香(((
我以前总是习惯睡觉之前洗澡洗完进被窝,可是终于也体会到原来它也可以有开拓新纪元的意义啊!
哈哈哈,这几天天天丧天天把自己拔起来......
洗衣服的时候照镜子觉得好憔悴啊我= = 大概不好好吃饭,吃外卖太多,又不运动又压力大
大概需要一个男盆友和我去吃食堂去跑步监督我= =
(所以我...诶)
还有,今天决京拿了mvp 小青蛙给我寄来了新的明信片,才终于有点明白为什么这个辣鸡游戏可以这么火牵挂或者什么或者什么的 意义
有什么不开心嘛 那决京拿一局MVP就能解决
如果一局不行那就两局(这才是他们玩游戏的意义啊!)
哇哈哈哈记事本 的字体可以改,这体验太棒了我要做一个技术宅哇啦啦啦
画重点:体验太棒了
理解题意还是比较重要的,对于这些小木棍,【正好】组成正方形
【正好】边长*4
并且不能切割,所以只是加来加去,判断组合方式
(可以重复)
【剪枝】
:
这个思想有点重要”
1.如果最长的比边长大放弃(因为不能切割)
2.如果sum总长/4 不是整数 也切去
***用%4 看
3,都满足的话,其实前三块边长构造好了直接退出-再简化了计算
(第四个也是这样,就emm)
其他需要注意的...大概写一下伪代码就是
读入n,
判断两个剪枝
dfs(array,vis,0,0,0)
(array,vis,num,len+array[i],i/s)
传进的存储的这个数组/是否进行了访问
后面的是:已经租好了几个(num)
已经存好了的长度
从第几个开始继续往后找
dfs内部:
判断num==3
for循环,这么多里面
没有到visit的
若相加<,标记,继续dfs
若相加等于,标记,继续dfs num+1
若都不是,取消标记,继续下一个for循环里的i
最后注意一下,如果用过了(continue而不是return)
if (vist[i])
continue;
以及什么时候返回true或者是false,总不能for都完了还没找到匹配的-你false去吧。
代码实现
#include<iostream>
#include<algorithm>
using namespace std;
int cmp(const void* a, const void* b) //降序
{
return *(int*)b - *(int*)a;
}
int n; //木棒数量
int side; //正方形边长
bool dfs(int* stick, bool* vist, int num, int len, int s) //num:已组合的正方形的边数 len:当前组合的边已组合的长度,len<=side
{ //s:stick[]的搜索起点
if (num == 3) //剪枝3,当满足剪枝1和2的要求时,只需组合3条side,剩下的棒子必然能够组成最后一条side
return true;
for (int i = s; i<n; i++)
{
if (vist[i])
continue;
vist[i] = true;
if (len + stick[i]<side)
{
if (dfs(stick, vist, num, len + stick[i], i)) //继续构建当前side
return true;
}
else if (len + stick[i] == side)
{
if (dfs(stick, vist, num + 1, 0, 0)) //构建新side
return true;
}
vist[i] = false;
}
return false;
}
int main(void)
{
int time;
cin>> time;
for (int t = 0; t<time; t++)
{
int sum = 0; //所有木棒长度之和
cin >> n;
int* stick = new int
;
bool* vist = new bool
;
for (int i = 0; i<n; i++)
{
cin >> stick[i];
vist[i] = false;
sum += stick[i];
}
if (n<4 || sum % 4 != 0) //剪枝1,不能构成正方形
{
cout << "no" << endl;
continue;
}
qsort(stick, n, sizeof(int), cmp); //降序排列,先组合长棒,因为长棒相对于短棒的组合灵活性较低
side = sum / 4; //边长
if (side<stick[0]) //剪枝2,side<max_stick
{
cout << "no" << endl;
continue;
}
if (dfs(stick, vist, 0, 0, 0))
cout << "yes" << endl;
else
cout << "no" << endl;
delete stick;
delete vist;
}
return 0;
}
感谢来源http://blog.csdn.net/lyy289065406/article/details/6647955
//另有个帖子说其实不排序也可以,大概排序了剪枝方便一点...什么的哎呀不管了
【其实有很多事情只要花一点点功夫或者是小改变,,,效果会特别惊人= =】
】
【笑cry:可能下次,这个治疗丧的办法就不管用了】
=========题外话============
(如果你把粘贴的代码拿走了之后还看到这里,那么谢谢你呀!)
【我平时运动的太少啦!!!!!!!如果可以去操场跑圈儿啊,我都要生锈啦】]
"其实你是 一幅画 狠狠地往人心上挂
其实想想我可能也会经常丧....只不过很多事情我都不去想而已= =
并且不去想的太多了,以及有什么是什么,根本不考虑后果
结果回来之后又丧又拖延又吃东西,六点半才去洗澡....
结果复活了啊啊啊啊啊啊啊本来还在咒骂怎么洗个澡都冷得 不行
原来大概是我温度太低了... 手感和身上的感觉不一样啊
温度上去之后出来就不冷了....真的好舒服啊(((
记得她之前跟我讲过,北方人不会明白,南方人的热水澡,热气便从头浇到脚的感觉 热气从内向外散发 而且我的沐浴露又超级香(((
我以前总是习惯睡觉之前洗澡洗完进被窝,可是终于也体会到原来它也可以有开拓新纪元的意义啊!
哈哈哈,这几天天天丧天天把自己拔起来......
洗衣服的时候照镜子觉得好憔悴啊我= = 大概不好好吃饭,吃外卖太多,又不运动又压力大
大概需要一个男盆友和我去吃食堂去跑步监督我= =
(所以我...诶)
还有,今天决京拿了mvp 小青蛙给我寄来了新的明信片,才终于有点明白为什么这个辣鸡游戏可以这么火牵挂或者什么或者什么的 意义
有什么不开心嘛 那决京拿一局MVP就能解决
如果一局不行那就两局(这才是他们玩游戏的意义啊!)
哇哈哈哈记事本 的字体可以改,这体验太棒了我要做一个技术宅哇啦啦啦
画重点:体验太棒了
相关文章推荐
- POJ 2362 Square (DFS +剪枝)
- hdu1455 && poj1011 Sticks(深度优先搜索 DFS 经典剪枝 详解)
- POJ 2362 dfs 剪枝
- hdoj 1455 && nyoj 293 && poj 1110 Sticks 【DFS + 剪枝 + 剪枝 + 剪枝 + 。。。+ 剪枝】
- POJ 2362/HDU 1518 dfs 剪枝
- POJ 2362 HDOJ 1518 Square DFS剪枝
- poj 2362 Square(dfs, 剪枝)
- poj&nbsp;1190&nbsp;生日蛋糕&nbsp;剪枝dfs
- POJ 2362 square &&POJ 1011 Sticks 记忆化搜索 DFS
- POJ 2362 DFS+剪枝
- poj 1014 && zoj 1149 Dividing --- dfs剪枝
- poj 1011/2362 dfs+剪枝(拼木棍)
- ACM: 一题DFS(深搜,剪枝) poj 1011
- POJ 2362 && HDU 1518 Square(dfs)
- POJ 1562 && ZOJ 1709 Oil Deposits(简单DFS)
- POJ 生日蛋糕(DFS 巧妙剪枝)
- HDU_4123 && POJ_4003 Bob’s Race (dfs / bfs + RMQ + 尺取)
- ACM: dfs题 poj 1321 (n皇后问题)
- POJ_S1E03_DFS&BFS(3)
- POJ 2192 Zipper [dfs+剪枝 || dp]