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 }

 

posted @ 2018-02-23 14:18  卉卉卉大爷  阅读(223)  评论(0编辑  收藏  举报