POJ 2362(Square-搜索剪枝1-相对顺序)
Language:
Square
Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick – an integer between 1 and 10,000.
Output
For each case, output a line containing “yes” if is is possible to form a square; otherwise output “no”.
Sample Input 3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5 Sample Output yes no yes Source |
《搜索是怎样剪枝的-1》
1.只要找到3条边。
2.从大到小顺序找。
3.每次搜边时要确定边的相对顺序唯一(直接从TLE→秒)
#include<cstdio>include<cstdlib>
include<algorithm>
include<functional>
include<cstring>
include<iostream>
using namespace std;
define MAXM (20+10)
int tt,n,a[MAXM],cnt,len; bool b[MAXM],flag; bool dfs(int l,int x,int pre) { // cout<<l<<' '<<x<<' '<<kth<<endl; if (x==len) {l++;x=0;pre=n-1;} if (l==4) { return 1; } for(int i=pre-1;i;i--)
if (!b[i]&&x+a[i]<=len) { b[i]=1; if (dfs(l,x+a[i],i)) return 1; b[i]=0; // if (!x) return 0; } return 0; } int main() { scanf("%d",&tt); while (tt--) { cnt=0; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); cnt+=a[i];b[i]=0; } sort(a+1,a+1+n); if (n<4||cnt%4||a[n]>cnt/4) { printf("no\n");continue; } b[n]=1;len=cnt/4; if (dfs(1,a[n],n)) { printf("yes\n"); } else printf("no\n"); }
return 0; }