二分算法(一个简单且非常实用的算法)
算法思想,通过中间值不断缩短检索区域 --> 大大降低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;
}
标签:二分,正整数,cout,食量,面碗,半径
From: https://www.cnblogs.com/TFOREVERY/p/17239608.html