POJ 2362 Square
2017-01-17 16:42
369 查看
** 题目地址:POJ 2362
题目大意:给n根长度不一的木棍,问是否能构成一个正方形
解题思路:由于题目限定4<=n<=20,可以直接用DFS,但是必须剪枝。首先可以很容易得到以下两个剪枝条件:
a . 木棍总长度sum必须可以被4整除
b . 最长的木棍的长度不得长于正方形边长
根据这两个条件之后,如果可以拼凑出正方形的3条边,由于sum一定,那么就一定可以组成一个正方形,否则输出”no”.所以
c . 深搜能得到正方形的三条边即可。**
题目大意:给n根长度不一的木棍,问是否能构成一个正方形
解题思路:由于题目限定4<=n<=20,可以直接用DFS,但是必须剪枝。首先可以很容易得到以下两个剪枝条件:
a . 木棍总长度sum必须可以被4整除
b . 最长的木棍的长度不得长于正方形边长
根据这两个条件之后,如果可以拼凑出正方形的3条边,由于sum一定,那么就一定可以组成一个正方形,否则输出”no”.所以
c . 深搜能得到正方形的三条边即可。**
#include<iostream> #include<algorithm> #include<string.h> #include<stdio.h> using namespace std; int n;//木棍个数 bool visit[21];//是否被访问 int stick[21];//木棍长度 int side;//正方形边长 bool cmp(int a,int b) { return a>b; } bool dfs(int num,int len,int root) {//num为成功凑成的边数 //len为当前正在拼凑的边的长度 //root为起始访问的木棍数组的下标 if(num==3) return true; for(int i=root;i<n;i++) { if(visit[i]) continue; visit[i]=true; if(len+stick[i]<side)//若小于side { if(dfs(num,len+stick[i],i+1))//加上stick[i]产生新len, return true; //i+1可以避免没有意义的循环 //else visit[i]=false; //若加上stick[i]后使得无法成功拼成正方形,则放弃当前边 } else if(len+stick[i]==side)//若相等,则开始拼凑下一条边 { if(dfs(num+1,0,0)) return true; //else visit[i]=false; //同上 } visit[i]=false;//若大于side则暂时放弃当前边 } return false; } int main() { int t; cin>>t; while(t--) { cin>>n;int sum=0; for(int i=0;i<n;i++) { cin>>stick[i]; sum+=stick[i]; } sort(stick,stick+n,cmp);//先将木棍长度按照降序排列 side=sum/4; memset(visit,false,sizeof(visit)); if(sum%4!=0||stick[0]>side)//剪枝1:总长度不能被4整除 { //剪枝2:最长木棍长于正方形边长 cout<<"no"<<endl; continue; } if(dfs(0,0,0)) cout<<"yes"<<endl; else cout<<"no"<<endl; } return 0; }
相关文章推荐
- POJ 2362 square(DFS范例题)
- POJ 2362 Square(DFS回溯构造)
- 【POJ】2362 Square(DFS)
- poj 2362 Square(dfs, 剪枝)
- POJ 2362 Square 同1011
- POJ 2362 Square(搜索+剪枝)
- DFS POJ 2362 Square
- POJ 2362 Square
- dfs Square poj 2362
- POJ-2362-Square
- POJ 2362(Square-搜索剪枝1-相对顺序)
- poj 2362 Square
- POJ 2362 Square
- poj 2362 hdoj 1518 Square(搜索)
- poj 2362 Square
- POJ 2362 Square (搜索 + 剪枝)
- poj 2362 Square
- poj 2362 Square
- poj 2362 hdoj 1518 Square(搜索)
- poj 2362 Square