题意:有f+1个人分n块披萨,每个人要求分得的面积一样,且披萨只能被切开而不能重新组合,求每个人能分到的最大面积v。
注意,主人本身有算进去。
上界:只有一个人吃,即为饼的size之和。
下届:f趋于无穷大,分的饼面积趋于0。
注意的地方是,将面积放大1000000,倍 相当于 e-6的精度。
代码:
#include <stdio.h>
#include <math.h>
const double Pi = 4 * atan(1);
const int Maxn = 10001;
int f, n;
long long size[Maxn];
bool check(long long mid)
{
long long t = 0;
for (int i = 0; i < n; i++)
{
t += size[i] / mid;
}
return t >= f;
}
long long find(long long low, long long high)
{
while (low < high)
{
long long mid = (low + high) >> 1;
if (check(mid))
low = mid + 1;
else
high = mid;
}
return low;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int ncase;
scanf("%d", &ncase);
while (ncase--)
{
long long upsize = 0;
long long ans = 0;
scanf("%d%d", &n, &f);
f++;
for (int i = 0; i < n; i++)
{
int r;
scanf("%d", &r);
size[i] = Pi * r * r * 1000000;//考虑精度差,将其放大1000000倍变成整数来二分
upsize += size[i];
}
printf("%.4lf\n", find(0, upsize) / 1000000.0);
}
return 0;
}
hoj 2278 也是二分的题目。
求指定ip是否在一段ip内。
代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
struct IP
{
long long star;
long long end;
bool operator < (const IP & a)const
{
return star < a.star;
}
} ip[1000005];
long long count(char str[])
{
int b[4];
sscanf(str, "%d.%d.%d.%d", b, b + 1, b + 2, b + 3);
return b[0] * 1e9 + b[1] * 1e6 + b[2] * 1e3 + b[3];
}
int main()
{
char str[30];
int n = 0;
while (scanf("%s", str) != EOF)
{
getchar();
if (str[0] == '#')
break;
ip[n].star = count(str);
scanf("%s", str);
getchar();
ip[n].end = count(str);
if (ip[n].star > ip[n].end)
{
long long t;
t = ip[n].star;
ip[n].star = ip[n].end;
ip[n].end = t;
}
n++;
}
sort(ip, ip + n);
while (scanf("%s", str) != EOF)
{
getchar();
long long tmp = count(str);
int low = 0;
int high = n - 1;
bool flag = false;
while (low <= high)
{
int mid = (low + high) >> 1;
if (tmp >= ip[mid].star && tmp <= ip[mid].end)
{
flag = true;
break;
}
if (tmp < ip[mid].star)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
if (flag == true)
printf("yes\n");
else
printf("no\n");
}
return 0;
}