计蒜客:等边三角形(dfs+剪枝)

蒜头君手上有一些小木棍,它们长短不一,蒜头君想用这些木棍拼出一个等边三角形,并且每根木棍都要用到。 例如,蒜头君手上有长度为 11,22,33,33 的4根木棍,他可以让长度为11,22 的木棍组成一条边,另外 22 跟分别组成 22 条边,拼成一个边长为 33 的等边三角形。蒜头君希望你提前告诉他能不能拼出来,免得白费功夫。

输入格式

首先输入一个整数 n(3 \le n \le 20)n(3n20),表示木棍数量,接下来输入 nn 根木棍的长度 p_i(1 \le p_i \le 10000)pi(1pi10000)。

输出格式

如果蒜头君能拼出等边三角形,输出"yes",否则输出"no"

解题思路:

使用dfs计算三条边的长度,枚举每根木棍加在l1,l2,l3三条边上不同的情况,若dfs中满足三边都等于sum/3,则yes,否则no

剪枝:dfs过程中有某条边大于sum/3则回溯,以及枚举到第n根木棍还没找到等边三角形,则退出

 1 #include <iostream>
 2 using namespace std;
 3 int t=0;
 4 int sum=0;
 5 int n;
 6 int len[20];
 7 void dfs(int k,int l1,int l2,int l3){
 8     if(l1>sum||l2>sum||l3>sum)//剪枝条件
 9         return;
10     if(l1==sum&&l2==sum&&l3==sum){//满足条件
11         cout<<"yes"<<endl;
12         exit(0);
13         return;
14     }
15     if(k==n)//枚举到第n根木棍
16         return;
17     dfs(k+1,l1+len[k],l2,l3);//第k+1根木棍分别加在l1,l2,l3上不同的dfs
18     dfs(k+1,l1,l2+len[k],l3);
19     dfs(k+1,l1,l2,l3+len[k]);
20 }
21 int main(){
22     cin>>n;
23     for(int i=0;i<n;i++){
24         cin>>len[i];
25         sum+=len[i];
26     }
27     if(sum%3!=0){//总长度不是3的倍数,直接no
28         cout<<"no"<<endl;
29         return 0;
30     }
31     sum/=3;//设定sum等边三角形一条边的长度
32     dfs(0,0,0,0);
33     if(!t)
34         cout<<"no";
35     return 0;
36 }

 

 

posted @ 2020-08-07 17:20  nilbook  阅读(234)  评论(0编辑  收藏  举报