POJ - 1011

传送门

POJ - 1011

题面:

Sticks
Time Limit: 1000MS Memory Limit: 10000K

Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

Input

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

Output

The output should contains the smallest possible length of original sticks, one per line.

Sample Input

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample Output

6
5

翻译

乔治拿起一根同样长度的木棍,随意地将其剪断,直到所有的部分长到不超过50个单位。
现在他想把木棒恢复到原来的状态,但是他忘记了他原来有多少根木棒,有多长。
请帮助他设计一个程序,计算出这些棍子的最小原始长度。
以单位表示的所有长度都是大于零的整数。

输入

输入包含两行代码块。
第一行是切割后的木棒零件数量,最多64根。
第二行包含由空格分隔的部分的长度。
文件的最后一行包含0。

输出

输出应该包含尽可能小的原始棒的长度,每一行一个。

思路

首先先判断每一根棍子可能有多长,将数据,从大到小代入进去DFS,重复长度的,被拒一根全部跳过,要注意超时。

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
bool fuck(int a,int b)
{
	return a>b;
}
int m[101],mm[101],n,k,c,x,gg;
int check(int y,int z)
{
	if(y==0&&z==0)
		return 1;
	if(y==0&&z!=0)
		return 0;
	if(z==0)
		z=x;
	if(z==x)
		gg=1;
	else
		gg++;
	for(int i=gg;i<=n;i++)
	{
		if(mm[i]==1)
			continue;
		if(mm[i-1]==0&&m[i-1]==m[i])
			continue;
		if(z-m[i]>=0)
		{
			mm[i]=1;
			gg=i;
			if(check(y-1,z-m[i])==1)
				return 1;
			else
			{
				mm[i]=0;
				if(z==x||m[i]==z) 
					return 0;
				continue;
			}
		}
	}
	return 0;
}
int main()
{
	int a,b;
	bool ok=0;
	while(1)
	{
		memset(m,0,sizeof(m));
		cin>>n;
		if(n==0)
		{
			break;
		}
		c=0;
		for(int i=1;i<=n;i++)
		{
			cin>>m[i];
			c+=m[i];
		}
		sort(m+1,m+n+1,fuck);
		ok=0;
		for(int i=m[1];i<=c/2;i++)
		{
			if(c%i==0)
			{
				k=0;
				memset(mm,0,sizeof(mm));
				x=i;
				if(check(n,x)==1)
				{
					ok=1;
					cout<<i<<endl;
					break;
				}
			}
		}
		if(ok==0)
			cout<<c<<endl;
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值