题目:
等边三角形
Description
蒜头君手上有一些小木棍,它们长短不一,蒜头君想用这些木棍拼出一个等边三角形,并且每根木棍都要用到。例如,蒜头君手上有长度为1,2,3,3的4根木棍,他可以让长度为1,2的木棍组成一条边,另外2跟分别组成2条边,拼成一个边长为3的等边三角形。蒜头君希望你提前告诉他能不能拼出来,免得白费功夫。
Input
首先输入一个整数n(3≤n≤20),表示木棍数量,接下来输入n根木棍的长度pi(1≤pi≤10000)。
Output
如果蒜头君能拼出等边三角形,输出yes,否则输出no。
Sample Input 1
5
1 2 3 4 5
Sample Output 1
yes
Sample Input 2
4
1 1 1 1
Sample Output 2
no
反思:
这个题和以往的dfs模板是不太一样的,但也都大同小异,这次我听了y总的视频,有了一种感觉,就是一边写一边想,写着写着就成功了(就比如先写主函数,然后写dfs,思路一直很流畅),当然我刷的题还是太少,需要继续努力
这题的思路还是挺好理解的,就是先假设三边都是0(同时再加一个计数的),之后将所有的可能通过dfs遍历出来,符合条件时就返回yes,我感觉这又是一种思维方式,一种做题模板,因为在此之前我只会做那种 上下左右 遍历二维数组的那种模式的题
我认为这题的关键在于这里:
充分理解了这里就不难做这一类的题了,其实就是比如多个边,第一个边先给a,不够sum/3,再继续往a加,a加不了了,再往b加。。。一个大的递归,千万不要将它想的太复杂!!! 只不过是3个语句,简单来看就是,第一个边先给a,a递归后所有情况要是都不行,就第一个边给b,b不行给c,依次递归,遍历所有的可能
不多说,上代码:
#include"iostream"
#include"algorithm"
using namespace std;
int cnt = 0;
int v[25];
int n,sum = 0,flag = 0;
void dfs(int a,int b,int c,int cnt){
if(cnt == n && a == b && b == c){
flag = 1;
return ;
}
if(a > sum/3 || b > sum/3 || c > sum/3 || cnt > n) return;
dfs(a+v[cnt],b,c,cnt + 1);
dfs(a,b+v[cnt],c,cnt + 1);
dfs(a,b,c+v[cnt],cnt + 1);
}
int main(){
cin >> n;
for(int i = 0;i < n;i ++){
cin >> v[i];
sum += v[i];
}
if(sum % 3 != 0){
cout << "no";
return 0;
}
dfs(0,0,0,0);
if(flag == 1){
cout << "yes";
}else{
cout << "no";
}
return 0;
}
追求需要思索
思索需要孤独
有时,凄清的身影
便是一种蓬勃
而不是干枯
两个人
也可以是痛苦
一个人
也可以是幸福
当你从寂寞中走来
道路便在你眼前展开
选自《孤独》——汪国真