二分

二分算法(一个简单且非常实用的算法)

算法思想,通过中间值不断缩短检索区域 --> 大大降低T的可能性 --> 只要是检索的题目都可以用二分查找来解决

算法思路:

1.确定左右边界
2.每次都要更新中间值
注意:你答案的更新并不是跟随中间值的更新一起的,而是在条件满足的时候进行更新

例题(模板)

/*

  • 题目
    众所周知,X_Y_H的食量小的可怕!作为X_Y_H的队友,CCCChen要照顾他的生活起居。
    这天X_Y_H想吃面,便吩咐CCCChen去给他买一碗面。
    CCCChen到了面馆,发现这里有R-L+1个半径互不相同的圆形碗,这些碗的半径均为正整数且大于等于L并小于等于R。
    已知X_Y_H的食量是n单位,他想在X_Y_H能吃饱的前提下用一个半径最小的碗装面,
    你能帮他算出他应该要一个半径为多少的碗来装面吗?
    为便于计算,我们假设一个碗能装下k*r2单位的面,其中k为系数,r为碗口的半径,保证k为正整数。
  • 输入
    第一行包括1个正整数t(1≤t≤106),表示有t组数据。
    接下来t行,每一行包括4个正整数
    n(1≤n≤109),k(1≤k≤1000),L,R(1≤L≤R≤106),
    分别表示X_Y_H的食量、面碗的系数、最小面碗半径与最大面碗半径。
  • 输出
    共t行,一行一个整数表示能装下满足X_Y_H的食量的面的半径最小的碗的半径,如果没有这样的碗则输出”-1”(不包括引号)。

*/

ACODE

#include <bits/stdc++.h>

#define endl '\n'
#define int long long

using namespace std;

int32_t main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t; cin >> t;
    while (t --> 0){
        int n,k,l,r; cin >> n >> k >> l >> r;
        if(n > k*r*r)cout << -1 << endl;
        else{
            int L=l,R = r;
            int ans;
            while (L <= R){
                int mid = (L+R)/2;
                if(mid*mid*k >= n){
                    ans = mid;
                    R = mid-1;
                }else {
                    L = mid+1;
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}
posted @ 2023-03-21 12:51  TFOREVERY  阅读(13)  评论(0编辑  收藏  举报