题目地址:点击打开链接
题意:给你n个棍子,这些棍子的长度告诉你,问把这个棍子全都用上,能否组成一个正方形
思路:用回溯一般就是求可能情况(这种情况能否组成),所有组成情况的最值,能组成这种情况的个数(八皇后问题),这道题的减枝想到了还容易wrong,注意看我注释掉的部分,减枝比较容易想,每次只找比它长的,因为组成一条正方形的边的长度肯定有长有短,而这道题只求可能情况,所以这种减枝方法可行
AC代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <cstring> #include <climits> #include <cmath> #include <cctype> using namespace std; int a[25]; int visit[25]; int edge; int m; bool flag; void dfs(int start,int sum,int now) { int i; if(flag) return; if(sum == 4) { flag = true; return; } for(i=start; i<m; i++) { if(!visit[i]) { visit[i] = 1; if(now + a[i] == edge) { //dfs(i+1,sum+1,0); dfs(0,sum+1,0);//组成一条边的时候要从头开始搜 } else if(now + a[i] < edge) { dfs(i+1,sum,now+a[i]); } visit[i] = 0; } } } int main() { int t,i; scanf("%d",&t); while(t--) { flag = false; int sum = 0; memset(visit,0,sizeof(visit)); scanf("%d",&m); for(i=0; i<m; i++) { scanf("%d",&a[i]); sum += a[i]; } if(sum % 4 != 0) { printf("no\n"); continue; } edge = sum / 4; for(i=0; i<m; i++) { if(a[i] > edge) break; } if(i != m) { printf("no\n"); continue; } sort(a,a+m); dfs(0,0,0); if(flag) printf("yes\n"); else printf("no\n"); } return 0; }
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <cstring> #include <climits> #include <cmath> #include <cctype> using namespace std; int a[25]; int visit[25]; int edge; int m; bool flag; void dfs(int sum,int now) { int i; if(flag) return; if(sum == 4) { flag = true; return; } for(i=0; i<m; i++) { if(!visit[i]) { visit[i] = 1; if(now + a[i] == edge) { dfs(sum+1,0); } else if(now + a[i] < edge) { dfs(sum,now+a[i]); } visit[i] = 0; } } } int main() { int t,i; scanf("%d",&t); while(t--) { flag = false; int sum = 0; memset(visit,0,sizeof(visit)); scanf("%d",&m); for(i=0; i<m; i++) { scanf("%d",&a[i]); sum += a[i]; } if(sum % 4 != 0) { printf("no\n"); continue; } edge = sum / 4; for(i=0; i<m; i++) { if(a[i] > edge) break; } if(i != m) { printf("no\n"); continue; } dfs(0,0); if(flag) printf("yes\n"); else printf("no\n"); } return 0; }