POJ_2362_Square

来源:互联网 发布:阿里云 省市区api 编辑:程序博客网 时间:2024/05/24 15:37
Square
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 21782 Accepted: 7606

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

34 1 1 1 15 10 20 30 40 508 1 7 2 6 4 4 3 5

Sample Output

yesnoyes

Source

Waterloo local 2002.09.21

dfs这个题目有几个剪枝需要做。
1.小于4的不能组成正方形
2.周长不是4的整数倍的不行
3.找三边的长度符合要求(四分之一周长)第四边会自动满足
4.最重要的一点,边长的组合是组合问题,因此在算某个边长的时候,
   之后加上的棍比之前的短就可以,因此dfs要给for的起点(我是从大往小做的)
#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;const int M=25;int l[M];int isu[M];int f;int n;int r;bool cmp(int a,int b){    return a>b;}void dfs(int tot,int nl,int st){    if(f)        return;    if(nl==3)    {        f=1;        return;    }    for(int i=st;i<n;i++)    {        if(f)            return;        if(!isu[i])        {            //cout<<tot<<" "<<nl<<" "<<i<<endl;            int tmp=l[i]+tot;            if(tmp>r)                continue;            else if(tmp==r)            {                isu[i]=1;                dfs(0,nl+1,0);                isu[i]=0;            }            else            {                isu[i]=1;                dfs(tmp,nl,i);                isu[i]=0;            }        }    }}int main(){    //freopen("1.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {        r=0;        f=0;        scanf("%d",&n);        for(int i=0;i<n;i++)        {            scanf("%d",&l[i]);            r+=l[i];            isu[i]=0;        }        if(n<4||r%4!=0)        {            printf("no\n");            continue;        }        sort(l,l+n,cmp);        r/=4;              //周长变边长        if(l[0]>r)               //木棍最大长度长过了边长        {            printf("no\n");            continue;        }        dfs(0,0,0);        if(f)            printf("yes\n");        else            printf("no\n");    }    return 0;}
dfs还有一种写法
bool dfs(int tot,int nl,int st){    if(tot==r)    {        tot=0;        nl++;        st=n-1;        if(nl==3)            return 1;    }    for(int i=st;i>=0;i--)    {        if(!isu[i])        {            //cout<<tot<<" "<<nl<<" "<<i<<" ";            int tmp=l[i]+tot;            if(tmp>r)                continue;            else            {                isu[i]=1;                if(dfs(tmp,nl,i))                    return 1;                isu[i]=0;            }        }    }    //cout<<endl;    return 0;}


0 0
原创粉丝点击