hrbust 2115,哈理工oj 2115 Equal【dfs+剪枝】

Equal

Time Limit: 1000 MS

Memory Limit: 65536 K

 

Total Submit: 52(20 users)

Total Accepted: 20(15 users)

Rating: 

Special Judge: No

 

Description

Given a set of positive numbers, can you find that if these numbers can be separated into 6 subsets, so that the sum of each subsets is equal.

For example, a set of {1, 1, 1, 1, 1, 1} can meet the condition, but {1, 2, 3, 4, 5, 6} can not.

 

Input

The input contains multiple test cases. 

The first line contains a integer T, means the number of test cases.

Each test case begins with a integer N(N<=30) the number of numbers in the set, followed by N integers, each number is between 1 and 10000.

 

Output

For each test case print "yes" if the set full-fill the problem, and "no" if not.

Sample Input

2

20 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 4 3 2 1

20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Sample Output

yes

no

Source

ACM-ICPC黑龙江省第九届大学生程序设计竞赛选拔赛(2)

 

题目大意:给你n个数组成的一个数集。然后把它们分成六个子数集,使得他们的每一个子数集合内的数据加和都相等。问能否分成这六个子数集,如果可以,输出yes,否则输出no。


思路:dfs+剪枝+剪枝+剪枝==AC

剪枝1、首先我们要分六个子数集使其和都相等,辣么分成六个子数集的和一定是原来数集和的1/6,辣么如果原先的数集的和不是6的倍数,那么不好意识,没有这1/6的整数存在,那么直接输出no就好。

剪枝2、如果找到了结果,标记上一个变量ok=1,表示已经找到集合了,不需要继续dfs下去了,这个时候在每个地方都要return。

剪枝3、我就刚刚小剪了两刀,TLE,看来剪的还不够利索啊,我们单单dfs两个数据【cont(当前dfs到了第几个集合),now(当前集合的数字和)】看来是不行的,我就再加了一个元素k,遍历的时候,i从k开始遍历,当完成了一个集合的时候,再让k变成0,这样在dfs集合的时候,就更少的遍历已经选择过的数据了。

经过第二次强力剪枝,后台数据君也挡不住剪枝带来的输出,最终落败,还是告诉我我比他屌。

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[50];
int vis[50];
int sum;
int n;
int ok;
void dfs(int cont,int now,int k)
{
    if(ok==1)return ;
    if(cont==6)
    {
        ok=1;
        printf("yes\n");
        return ;
    }
    for(int i=k;i<n;i++)//从k开始遍历
    {
        if(vis[i]==0&&now+a[i]<=sum)
        {
            vis[i]=1;
            if(now+a[i]<sum)
            {
                dfs(cont,now+a[i],i);
            }
            if(now+a[i]==sum)
            {
                dfs(cont+1,0,0);
            }
            vis[i]=0;
            if(ok==1)return ;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        sum=0;
        ok=0;
        scanf("%d",&n);
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sort(a,a+n);
        reverse(a,a+n);
        if(sum%6==0)
        {
            sum/=6;
            dfs(0,0,0);
            if(ok==0)
            printf("no\n");
        }
        else
        {
            printf("no\n");
        }
    }
}














你可能感兴趣的:(2115,哈理工oj,2115,hrbust)