POJ 2362 -- Square
POJ 2362 -- Square
题意:
给定一堆不定长度的小棒子,问他们能否构成一个正方形。
解题思路:
DFS,排列树,即找到一个给出的木棍长度序列的全排列,使得能够形成一个正方形
所有木棍长度之和即为正方形的周长sum,正方形的边长即为sum/4,必须满足sum%4==0
需要组成四根长度为sum/4的木棍
所有小棒子中最长的一根,必须满足Max_length <= side,这是因为小棒子不能折断
当成功组合出3根长度为sum/4的木棍后,算法就可停止
啊...TLE,为什么呐~
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int maxm = 25;///木棍的根数4 <= M <= 20, 6 int sum;///正方形的周长 7 int m;///小木棍的根数 8 int stick[maxm];///记录小木棍长度的数组 9 bool dfs(int now,int len,int Count) 10 { 11 if(Count == 3) 12 { 13 return true; 14 } 15 for(int i=now;i<m;i++) 16 { 17 if(len + stick[i] == sum/4) 18 { 19 swap(stick[now],stick[i]); 20 if(dfs(now+1,0,Count++))///构建新木棍 21 return true; 22 ///进行回溯 23 swap(stick[now],stick[i]); 24 } 25 if(len + stick[i] < sum/4) 26 { 27 swap(stick[now],stick[i]); 28 if(dfs(now+1,len+stick[now],Count)) 29 return true; 30 swap(stick[now],stick[i]); 31 } 32 } 33 return false; 34 } 35 36 int main() 37 { 38 int n;///测试样例个数 39 while(cin>>n) 40 while(n--) 41 { 42 cin>>m; 43 sum = 0; 44 for(int i=0;i<m;i++) 45 { 46 cin>>stick[i]; 47 sum += stick[i]; 48 } 49 sort(stick,stick+m);///进行降序排列 50 if(m<4 || sum%4 != 0) 51 cout<<"no"<<endl; 52 else if(stick[0] > sum/4) 53 cout<<"no"<<endl; 54 else 55 { 56 if(dfs(0,0,0)) 57 cout<<"yes"<<endl; 58 else 59 cout<<"no"<<endl; 60 } 61 } 62 return 0; 63 }
将swap换掉,改成用数组visit[]即可通过,看样是swap操作比较费时
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxm = 25;///木棍的根数4 <= M <= 20, 5 int sum;///正方形的周长 6 int m;///小木棍的根数 7 int stick[maxm];///记录小木棍长度的数组 8 bool visit[maxm]; 9 bool dfs(int num,int len,int s) //num:已组合的正方形的边数 len:当前组合的边已组合的长度,len<=side 10 { //s:stick[]的搜索起点 11 if(num==3) //剪枝3,当满足剪枝1和2的要求时,只需组合3条side,剩下的棒子必然能够组成最后一条side 12 return true; 13 14 for(int i=s;i<m;i++) 15 { 16 if(visit[i]) 17 continue; 18 19 visit[i]=true; 20 if(len+stick[i]<sum/4) 21 { 22 if(dfs(num,len+stick[i],i)) //继续构建当前side 23 return true; 24 } 25 else if(len+stick[i]==sum/4) 26 { 27 if(dfs(num+1,0,0)) //构建新side 28 return true; 29 } 30 visit[i]=false; 31 } 32 33 return false; 34 } 35 36 int main() 37 { 38 int n;///测试样例个数 39 while(cin>>n) 40 while(n--) 41 { 42 cin>>m; 43 sum = 0; 44 int longest=0; 45 memset(visit,false,sizeof(visit)); 46 for(int i=0;i<m;i++) 47 { 48 cin>>stick[i]; 49 if(stick[i]>longest) 50 longest = stick[i]; 51 sum += stick[i]; 52 } 53 //sort(stick,stick+m);///进行降序排列 54 if(m<4 || sum%4 != 0) 55 cout<<"no"<<endl; 56 else if(longest > sum/4) 57 cout<<"no"<<endl; 58 else 59 { 60 if(dfs(0,0,0)) 61 cout<<"yes"<<endl; 62 else 63 cout<<"no"<<endl; 64 } 65 } 66 return 0; 67 }