文章目录
- 整数二分模板
- 模板1:满足条件的第一个数
- 模板2:满足条件的最后一个数
- 浮点数二分模板
- 一、Building an Aquarium
- 思路分析
- 具体代码
- 二、Tracking Segments
- 思路分析
- 具体代码
- 三、Wooden Toy Festival
- 思路分析
- 具体代码
- 四、路标设置
- 思路分析
- 具体代码
- 五、木材加工
- 思路分析
- 具体代码
整数二分模板
模板1:满足条件的第一个数
int bianrysearch(int l, int r) {
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
模板2:满足条件的最后一个数
int bianrysearch(int l, int r) {
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
浮点数二分模板
double bianrysearch(double l, double r) {
double eps = 1e-6;
while (r - l > eps) {
double mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
return l;
}
一、Building an Aquarium
Building an Aquarium
思路分析
二分
具体代码
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll t, n, x;
ll a[N];
bool check(ll mid) {
ll sum = 0;
for (int i = 1; i <= n; i++){
if (a[i] < mid) sum += mid - a[i];
}
return sum <= x;
}
int main() {
scanf("%lld", &t);
while (t--) {
scanf("%lld%lld", &n, &x);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
ll l = 1, r = 2e9 + 10;
while (l < r) {
ll mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
printf("%lld\n", l);
}
return 0;
}
二、Tracking Segments
Tracking Segments
思路分析
二分+前缀和
具体代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int t, n, m, q;
int s[N], pos[N];
ll preSum[N];
struct node{
int x, y;
}a[N];
bool check(int mid) {
for (int i = 1; i <= n; i++) s[i] = 0;
for (int i = 1; i <= mid; i++) s[pos[i]] = 1;
for (int i = 1; i <= n; i++) {
preSum[i] = preSum[i - 1] + s[i];
}
for (int i = 1; i <= m; i++) {
if (2 * (preSum[a[i].y ] - preSum[a[i].x - 1]) > a[i].y - a[i].x + 1) return true;
}
return false;
}
int main() {
cin >> t;
while(t--) {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> a[i].x >> a[i].y;
}
cin >> q;
for (int i = 1; i <= q; i++) {
cin >> pos[i];
}
if (!check(q)) {
puts("-1");
continue;
}
int l = 1, r = q;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
}
return 0;
}
三、Wooden Toy Festival
Wooden Toy Festival
思路分析
二分
具体代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int t, n;
int a[N];
bool check(int mid) {
int idx = 0, t1 = a[0] + 2 * mid;
while (a[idx] <= t1 && idx < n) idx++;
t1 = a[idx] + 2 * mid;
while (a[idx] <= t1 && idx < n) idx++;
t1 = a[idx] + 2 * mid;
while (a[idx] <= t1 && idx < n) idx++;
if (idx == n) return true;
return false;
}
int main() {
cin >> t;
while (t--) {
cin >> n;
int l = 0, r;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
r = a[n - 1];
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
}
return 0;
}
四、路标设置
路标设置
思路分析
二分,注意check函数写法
具体代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100000 + 10;
ll len, n, k;
ll a[N];
bool check(int mid) {
ll dif = 0;
for (int i = 1; i < n; i++) {
dif += (a[i] - a[i - 1] - 1) / mid;
}
return dif <= k;
}
int main() {
cin >> len >> n >> k;
ll l = 1, r = len;
for(int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
while (l < r) {
ll mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
return 0;
}
五、木材加工
木材加工
思路分析
二分
具体代码
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n, k;
ll a[N];
bool check(ll mid) {
ll sum = 0;
for (int i = 0; i < n; i++) sum += a[i] / mid;
return sum >= k;
}
int main() {
ll l = 0, r = 0;
cin >> n >> k;
for (int i = 0; i < n; i++) {
scanf("%lld", &a[i]);
r += a[i];
}
while(l < r) {
ll mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l <<endl;
return 0;
}