题目:http://acm.hdu.edu.cn/showproblem.php?pid=1059
题意:
数字1,2,3,4,5,6这六个数字各自出现不同的ai次,总次数不超过20000,将所有出现过的数字分成两组,问是否可以使两组数的和相等。
思路:
虽然总次数不超过20000,但当任意一个数字出现超过6次之后可以提前分配给两组,并不会对其它数字的分配产生影响,比如5,5,5,5,5,5,6,6,6,6,6,这里有六个5和五个6,这种情况是我能想到的单个数字出现次数最多的而且不能被提前分配的情况,假如有六个5,七个6,我们可以先分配两个6,得到六个5和五个6最后分配,也就是所有数字只要它出现次数超过6次,超过的偶数次就先分配掉,剩下的用6个for循环求和,如果能组合出总和的一半这种情况,就表示可以等分两组数字,否则不能。总和如果为奇数就不用算直接是不能等分了。
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int a1,a2,a3,a4,a5,a6;
int i1,i2,i3,i4,i5,i6;
int cas=0,sum,flag;
while(scanf("%d%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5,&a6)&&!(a1==0&&a2==0&&a3==0&&a4==0&&a5==0&&a6==0))
{
cas++;
printf("Collection #%d:\n",cas);
if(a1>6)a1=(a1%2)==1?7:6;
if(a2>6)a2=(a2%2)==1?7:6;
if(a3>6)a3=(a3%2)==1?7:6;
if(a4>6)a4=(a4%2)==1?7:6;
if(a5>6)a5=(a5%2)==1?7:6;
if(a6>6)a6=(a6%2)==1?7:6;
flag=0;
sum=a1+a2*2+a3*3+a4*4+a5*5+a6*6;
if(sum%2==1)
printf("Can't be divided.\n\n");
else
{
sum=sum/2;
for(i1=0;i1<=a1;i1++)
{
for(i2=0;i2<=a2;i2++)
{
for(i3=0;i3<=a3;i3++)
{
for(i4=0;i4<=a4;i4++)
{
for(i5=0;i5<=a5;i5++)
{
for(i6=0;i6<=a6;i6++)
{
if(sum==i1+i2*2+i3*3+i4*4+i5*5+i6*6)
{
flag=1;
break;
}
}
if(flag==1)break;
}
if(flag==1)break;
}
if(flag==1)break;
}
if(flag==1)break;
}
if(flag==1)break;
}
if(flag==1)
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
}
return 0;
}