二分答案

二分答案

总所周知,二分法查找一个数的时间复杂度为O(log n),所以在int范围内找一个数最多只需要30余次,在longlong范围内最多也只需要60余次。因此,我们可以利用二分这一优势查找答案。即,每次二分后判断该数是不是满足题目要求。

代码

const int N = 0x3f3f3f3f;
int main()
{
    int ans, l, r;
    int l = a, r = b;//a为上限,b为下限
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (check(mid))
        /*判断二分得到的mid是不是满足题目要求,
          并且将二分的上限或下限相对应的缩小*/
        {
            ans = mid;
            mid = l + 1;
        }
        else
            mid = r - 1;
    }
    cout << ans << endl;
    return 0;
}

下面以三道题目为例

1.吉首大学新星杯

(ps:这道题现在应该不能交了)
在这里插入图片描述
在这里插入图片描述

这道题n个整数表示樱花的高度,然后问你最小速度为多少时,所有樱花都可以在m秒内飘落完

二分代码:(由于该题评测关闭,不确定代码正确性):

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 0x3f3f3f3f;
int p[2000005];
int main()
{
    ll n, m, ans;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        scanf("%d", &p[i]);
    ll l = 1, r = N, mid;
    while (l <= r)
    {
        mid = (l + r) / 2;
        ll sum = 0;
        for (ll i = 0; i < n; i++)
        {
            sum += p[i] / mid;
            if (p[i] % mid != 0)
                sum++;
        }
        if (sum <= m)
        {
            ans = mid;
            r = mid - 1;
        }
        else
            l = mid + 1;
    }
    cout << ans << endl;
    return 0;
}
2.POJ2456
Aggressive cows

Description
Farmer John has built a new long barn, with 
N (2 <= N <= 100,000) stalls. 
The stalls are located along a straight 
line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don't like this barn layout and
become aggressive towards each other once put into a 
stall. To prevent the cows from hurting each other, 
FJ want to assign the cows to the stalls, such that the
minimum distance between any two of them is as large as
possible. What is the largest minimum distance?

Input
* Line 1: Two space-separated integers: N and C

* Lines 2..N+1: Line i+1 contains an integer stall 
location, xi

Output
* Line 1: One integer: the largest minimum distance

Sample Input
5 3
1
2
8
4
9

Sample Output
3

Hint
OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 
1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.

这题告诉你有n个隔间,然后有m头牛,一头牛住一个隔间,将m头牛分得尽可能开之后,两头牛的最小距离是多少

二分代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 0x3f3f3f3f;
int p[100005];
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        scanf("%d", &p[i]);
    sort(p, p + n);
    ll l = 0, r = p[n - 1] - p[0], ans;
    while (l <= r)
    {
        ll mid =(l+r)/2;
        ll sum = 0;
        int t = 0;
        for (int i = 0; i < n; i++)
        {
            if (p[i] - p[t] >= mid)
            {
                t = i;
                sum++;
            }
        }
        if (sum + 1 >= m)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
    cout << ans << endl;
    return 0;
}
3.计蒜客 存款

在这里插入图片描述
银行存钱问题,给你三个整数pytp:一年存钱可以获得的利息,y总共的年数,t最后获得的最少金额。问:小明最少每年投入多少钱,才能在y年后拥有至少t元。(小明每年将上一年的本金加利息一并存入银行)
坑点:上面两道题的二分答案的判断过程 即模板中的check过程都可以算完,最后再与题目要求比较,但是这道题会爆long long,所以我们每算一次sum就判断是不是超过最后所要拥有的金额t,如果是,那么直接跳出判断过程。
二分代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    long long y, t;
    double p;
    cin >> p >> y >> t;
    long long l = 1, r = t, mid, ans;
    while (l <= r)
    {
        int flag = 0;
        mid = (l + r) / 2;
        long long sum = 0;
        for (long long i = 1; i <= y; i++)
        {
            sum = (sum + mid) * (100 + p) / 100;
            if (sum >= t)
            {
                flag = 1;
                break;
            }
        }
        if (flag)
        {
            ans = mid;
            r = mid - 1;
        }
        else
            l = mid + 1;
    }
    cout << ans << endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值