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

来源:互联网 发布:用python写网络爬虫pdf 编辑:程序博客网 时间:2024/05/18 17:00

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");        }    }}














0 0