题意:给你一些木棒,问这些木棒首尾相连能不能连成一个正方形。
dfs+剪枝(卧槽一说剪枝瞬间高大上了
思路:首先看一看能不能被4整除,不能的话当然是NO;如果能的话,从头进行递归;
递归过程中,如果能够连成一条边,则继续往下递归,如果不能的话,立刻停止递归,消除标记。
AC代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; const int dx[4]= {1,0,-1,0}; const int dy[4]= {0,1,0,-1}; int a[105]; int ans,n,ave; int vis[105]; bool cmp(int a,int b) { return b>a; } int dfs(int s,int x,int cnt)//S是总和,X是下标,cnt记录了有几条边; { if(s==ave) { s=0; x=0; cnt++; if(cnt==4) { return 1; } } for(int i=x; i<n; i++) { if(!vis[i]) { vis[i]=1; if((s+a[i]<=ave)&&dfs(s+a[i],i+1,cnt))//往后找,找到一个未被标记的数,如果这个数加到总和里<=ave的话,继续递归,如果能够递归成功的话,结束循环,返回1; { return 1; } vis[i]=0; } } return 0; } int main() { int T; scanf("%d",&T); while(T--) { memset(vis,0,sizeof(vis)); scanf("%d",&n); int sum=0; for(int i=0; i<n; i++) { scanf("%d",&a[i]); sum+=a[i]; } int ans=0; if(sum%4==0) { ave=sum/4; ans=dfs(0,0,0); } if(ans) { printf("yes\n"); } else { printf("no\n"); } } return 0; }