1. 程式人生 > >藍橋 分巧克力(二分)

藍橋 分巧克力(二分)

  峰值記憶體消耗(含虛擬機器) < 256M
  CPU消耗 < 1000ms

  請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
  注意:
  main函式需要返回0;
  只使用ANSI C/ANSI C++ 標準;
  不要呼叫依賴於編譯環境或作業系統的特殊函式。
  所有依賴的函式必須明確地在原始檔中 #include <xxx>
  不能通過工程設定而省略常用標頭檔案。


  提交程式時,注意選擇所期望的語言型別和編譯器型別。

這個題一開始我是從邊長1開始遍歷,一直到巧克力不夠分給所有人(暴力),但只得87分,後來才知道要用二分簡化,從1到maxn,l = 1, r = maxn, i = (l + r) / 2,所有人都能分到就讓l = i + 1,反之就r = i - 1;要注意的是退出條件是l > r,而不是l >= r,因為l == r時,i有可能還沒取到l(r)。

AC程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;

const int maxn = 100010;
int n, k;
int a[maxn][2];

int main()
{
	scanf("%d%d", &n, &k);
	for(int i = 0; i < n; i++)
	{
		scanf("%d%d", &a[i][0], &a[i][1]);
	}
	int ans = 1;
	int l = 1, r = maxn;
	for(int i = (l + r) / 2; l <= r; i = (l + r) / 2)
	{
		int flag = 1;
		int t = k;
		for(int j = 0; j < n; j++)
		{
			int x = max(a[j][0], a[j][1]);
			int y = min(a[j][0], a[j][1]);
			int num = (x / i) * (y / i);
			t -= num;
			if(t <= 0)//退出條件:所有人都分到了巧克力
			{
				flag = 0;
				if(i > ans)
					ans = i;
				break;
			}
		}
		if(flag == 1)
			r = i - 1;
		else
			l = i + 1;
	}
	printf("%d\n", ans);
	return 0;
}