1. 程式人生 > >POJ 2362 Square

POJ 2362 Square

  1. 題目大意:給n根長度不一的木棍,問是否能構成一個正方形

  2. 解題思路:由於題目限定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; }