square(正方形)

poj 2362

题目大意:给出一些数,问你能不能把这些数,分成4堆,没堆的和相等

解决:dfs+回溯,此题用的剪枝稍微少一些就不行

#include <iostream> 
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <functional>
using namespace std;
int num[30],ave,n;

bool found;
bool vis[30];

bool check()
{
    for(int i=0;i<n;i++)if(!vis[i])return false;
    return true;
}

void dfs(int p,int cur_sum,int heap)
{
    if(found)return;
    if(heap==4 && check()){  found=true;  return; }
    for(int i=p;i<n;i++)
    {
        if(!vis[i] && cur_sum+num[i]<=ave )
        {
             vis[i]=1;
             if(cur_sum+num[i]==ave){if(heap+1<=4) dfs(0,0,heap+1);}
             else dfs(i+1,cur_sum+num[i],heap);
             vis[i]=0;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ave=0;
        found=false;
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i=0;i<n;i++){scanf("%d",num+i); ave+=num[i];} 
       //必须被4整除
        if(ave%4)puts("no");
        else
        {
            
            ave/=4;
            //按照从大到小排序
            sort(num,num+n,greater<int>()); 
           //必须所有的都小于平均数
            if(num[0]>ave)puts("no");
            else 
            { 
                dfs(0,0,0);
                if( found )puts("yes");
                else puts("no");
            }
         } 
    }
    system("pause");
    return 0;
}

 

 

转载于:https://www.cnblogs.com/hpustudent/archive/2011/09/17/2179995.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值