计蒜客:等边三角形(dfs+剪枝)
蒜头君手上有一些小木棍,它们长短不一,蒜头君想用这些木棍拼出一个等边三角形,并且每根木棍都要用到。 例如,蒜头君手上有长度为 11,22,33,33 的4根木棍,他可以让长度为11,22 的木棍组成一条边,另外 22 跟分别组成 22 条边,拼成一个边长为 33 的等边三角形。蒜头君希望你提前告诉他能不能拼出来,免得白费功夫。
输入格式
首先输入一个整数 n(3 \le n \le 20)n(3≤n≤20),表示木棍数量,接下来输入 nn 根木棍的长度 p_i(1 \le p_i \le 10000)pi(1≤pi≤10000)。
输出格式
如果蒜头君能拼出等边三角形,输出"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 }