P1577 切绳子

P1577 切绳子_第1张图片
P1577 切绳子_第2张图片

基本思路:
本题是为了求一个基础k,从这堆绳子中,能得到多少根k长的绳子。
那么,我们就可以依照二分法。
因为是从这批绳子中找最大值,那么k值必定不会超过这批绳子的最大值。
确定一个mid的k值,然后如果成立,那么k值最小便是这个值,我们只需要考虑从mid到max这部分区间里。重新找到一个成立的数,重复该步骤。
如果该mid的k值,不成立,那么就需要重新确立max值,需要从min到mid值里面找到一个成立的k值,然后再重复上面mid到max的值。
不断的二分,不断找能够成立的值。
最终二分结束,得到的结果便是最终结果了。

#include
#include

double lenth[10005];
int main()
{
	double max = 0;
	int n, k;
	scanf("%d%d", &n, &k);

	for (int i = 0; i < n; i++)
	{
		scanf("%lf", &lenth[i]);
		if (max < lenth[i])
			max = lenth[i];
	}

	double l = 0.00;
	double r = max;
	double length = 0;

	while (r - l > 1e-4)
	{
		int count1 = 0;
		double mid = (l + r) / 2;
		for (int i = 0; i < n; i++)
		{
			count1 += (int)(lenth[i] / mid);
			if (count1 >= k)
			{
				l = mid + 0.001;
				length = mid;	//如果这里改为length=mid+0.005,那么便是另一半正确。怎么改?
				break;
			}
		}

		if (count1 < k)
		{
			r = mid;
		}
	}


	length = (int)(length * 100);

	length = length / 100;
	printf("%.2lf", length);
	return 0;
}

改后代码:

#include
#include

double lenth[10005];
int main()
{
	double max = 0;
	int n, k;
	scanf("%d%d", &n, &k);

	for (int i = 0; i < n; i++)
	{
		scanf("%lf", &lenth[i]);
		if (max < lenth[i])
			max = lenth[i];
	}

	double l = 0.00;
	double r = max;
	double length = 0;

	while (r - l > 1e-4)
	{
		int count1 = 0;
		double mid = (l + r) / 2;
		length = mid + 0.001;//new
		for (int i = 0; i < n; i++)
		{
			count1 += (int)(lenth[i] / mid);
			if (count1 >= k)
			{
				//l = mid + 0.001;
				l = mid;
				//length = mid;	//如果这里改为length=mid+0.005,那么便是另一半正确。怎么改?
				break;
			}
		}

		if (count1 < k)
		{
			r = mid;
		}
	}
	length = (int)(length * 100);
	length = length / 100;
	printf("%.2lf", length);
	return 0;
}

总结:
二分这样子,确实今天学到了。
牛逼

你可能感兴趣的:(第一个月)