版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/88862900
title
CH 5E07
描述
有价值分别为1…6的大理石各a[1…6]块,现要将它们分成两部分,使得两部分价值之和相等,问是否可以实现。其中大理石的总数不超过20000。
输入格式
有多组数据!
所以可能有多行
如果有0 0 0 0 0 0表示输入文件结束
其余的行为6个整数
输出格式
有多少行可行数据就有几行输出
如果划分成功,输出Can,否则Can’t
样例输入
4 7 4 5 9 1
9 8 1 7 2 4
6 6 8 5 9 2
1 6 6 1 0 7
5 9 3 8 8 4
0 0 0 0 0 0
样例输出
Can’t
Can
Can’t
Can’t
Can
analysis
这题竟然没有容积,怪不得写的那么难受。。。。。其实就是个简单的板子一套,然而我。。。。。。好了,不说了,,,,,,,,。。。。。。。。。。。。。。。。。。。。。。
扫描二维码关注公众号,回复:
5698754 查看本文章
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+10;
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
int num[7],sum,f[maxn*6],w[maxn*6];
int main()
{
while (1)
{
memset(num,0,sizeof(num));
sum=0;
for (int i=1; i<=6; ++i)
read(num[i]),sum+=num[i]*i;
if (!sum) break;
int m=sum>>1,tot=0;
if (sum&1)
{
puts("Can't");
continue;
}
for (int i=1; i<=6; ++i)
{
int tmp=0;
for (int j=1; (j<<1)<=num[i]; j<<=1)
w[++tot]=j*i,tmp+=j;
w[++tot]=i*(num[i]-tmp);
}
f[0]=1;
for (int i=1; i<=tot; ++i)
for (int j=m; j>=w[i]; --j)
f[j]|=f[j-w[i]];
if (!f[m])
puts("Can't");
else
puts("Can");
}
return 0;
}