hoj 2651 Pie(二分)hoj 2278 (二分)

题意:有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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值