P1537 弹珠
题目描述
玛莎和比尔各自有自己的弹珠收藏。他们想重新分配收藏品,使两人能平等拥有弹珠。如果所有的弹珠的价值相同,那么他们就可以平分。但不幸的是,有一些弹珠更大,或者更美丽,所以,玛莎和比尔给每个弹珠一个1到6的价值。现在他们想平分这些弹珠,使每个人得到的总价值相同。不幸的是,他们发现,他们可能无法以这种方式分弹珠(即使弹珠的总价值为偶数)。例如,如果有一个价值为1、一个价值为3和两个价值为4的弹珠,这样他们就不能把弹珠分为价值相等的两部分。因此,他们想要你写一个程序,告诉他们是否能将所有弹珠分成价值相等的两部分。
输入格式:
输入文件有若干行,行中包含六个非负整数N1,。..,N6,其中mi是数值i的弹珠的价值。最大弹珠总数将达到20000。
输入文件的最后一行是0 0 0 0 0 0 。不要处理这一行。
输出格式:
对于每一组数据,输出"Collection #k:", k为输出的是第几组, 接着是"Can be divided." 或 "Can't be divided.".
每一组输出后多打一个空行。
输入样例:
1 0 1 2 0 0
1 0 0 0 1 1
0 0 0 0 0 0
输出样例:
Collection #1:\ Can't be divided.
Collection #2:\ Can be divided.
思路:
仔细一想,很简单的背包。 bool f[i]为能否凑到i; f[sum/2]即为答案。
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10;
const int M=130000;
int a[N];
int flag;
int n,sum;
bool f[M];
int main() {
n=1;
while(1) {
flag=0;
for(int i=1; i<=6; i++) {
scanf("%d",&a[i]);
if(a[i]==0)
flag++;
sum+=a[i]*i;
}
if(flag==6)
break;
if(sum%2==1)
printf("Collection #%d:\nCan't be divided.\n\n",n);
else {
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1; i<=6; i++)
for(int j=sum/2; j>=i; j--)
for(int k=1; k<=a[i]; k++)
if(j>=i*k && f[j-i*k])
f[j]=1;
if(f[sum/2])
printf("Collection #%d:\nCan be divided.\n\n",n);
else
printf("Collection #%d:\nCan't be divided.\n\n",n);
}
sum=0;
n++;
}
return 0;
}

浙公网安备 33010602011771号