Homework Introduction

二分

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int T, n;


struct node {
	int s, e, d;
} ;
node a[N];

int f(int x) {
	int res = 0;
	for (int i = 1; i <= n; i++)
		if (x >= a[i].s)
			res += (min(a[i].e, x) - a[i].s) / a[i].d + 1;
	return res;
}

main() {
	cin >> T;
	while (T--) {
		cin >> n;
		for (int i = 1; i <= n; i++)
			cin >> a[i].s >> a[i].e >> a[i].d;
		int l = 0, r = 2147483647;
		while (l < r) {
			int mid = l + r >> 1;
			if (f(mid) % 2 == 1)
				r = mid;
			else
				l = mid + 1;
		}
		int sum = f(l) - f(l - 1);
		if (sum % 2 == 1)
			cout << l << " "<<sum << '\n';
		else
			puts("There's no weakness.");
	}

	return 0;
}

路标设置
最大值最小

// 空旷指数
bool check(int x) {
	int last = a[1];
	int cnt = 0;
	for (int i = 2; i <= n; i++) {
		if (a[i] - last > x) {
			cnt++;
			last = last + x;
			i--; // 接下来还要在判断一次  a[i] 和 last
		} else
			last = a[i];
	}
	return cnt <= k;
}
// 跳石头
// 最小值最大

// 判断在给定的距离x下,
// 移走的是否数量能否小于等于 m
bool check(int x) {
	int last = 0, cnt = 0;
	for (int i = 1; i <= n; i++) {
		if (a[i] - last < x)
			cnt++;
		else
			last = a[i];
	}
	// 到终点也特判
	if(end - last < x) cnt++;
	return cnt<=m;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N], tmp;
long long res;
int main() {
	cin >> m >> n;
	for (int i = 1; i <= m; i++)
		cin >> a[i];
	sort(a + 1, a + 1 + m);
	for (int i = 1; i <= n; i++) {
		cin >> tmp;
		int t = lower_bound(a + 1, a + 1 + m, tmp) - a;
		if (t == 1)
			res += a[1] - tmp;
		else if (t == m + 1)
			res += tmp - a[m];
		else res += min(abs(a[t] - tmp), abs(tmp - a[t - 1]));
	}
	cout << res;
	return 0;
}
//x1<x2 , 且 f(x1)*f(x2)<=0
//意味着在 x1 和 x2 	 之间存在一个根
//
//mid = (l+r)/2;
//f(x1)*f(mid)<=0 根在 x1 - mid 之间
//否则 根在 mid 到 x2 之间

// 根的范围在 -100   到  100  之间
// 根与根的绝对值大于等于 1
#include <bits/stdc++.h>
using namespace std;
double a, b, c, d;
double eps = 1e-3;
// 一元三次函数
double f(double x) {
	return a * x * x * x + b * x * x + c * x + d;
}
int main() {
	cin >> a >> b >> c >> d;
	for (double i = -100 ; i < 100 ; i++) {
		// 判断 l - r 之间有没有根
		double l = i, r = i + 1;
		if (f(l) == 0) {
			printf("%.2lf ", l);
		}
		if (f(l)*f(r) < 0) { // 存在 根
			// 实数二分
			while (l + eps <= r) {
				double mid = (l + r) / 2;
				if (f(l)*f(mid) <= 0)
					r = mid;
				else
					l = mid;
			}
			printf("%.2lf ", l);
		}
	}
	return 0;
}
进击的奶牛

模板,最小值最大

// 在距离为 x 的情况能放置几头牛
bool check(int x) {
	int cnt=1, last = a[1];
	for(int i=2;i<=n;i++)
		if(a[i] - last>=x)
			last = a[i] , cnt++;
	return cnt>=m;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int a[N];
int ans;

// 实现check 函数
// 在每段和的最大值为 x 的情况下,是否能凑出 不超过 M 段
bool check(int x) {  // 数列分段I
	int sum = 1, last = a[1];
	for (int i = 2; i <= n; i++) {
		if (last + a[i] <= x)
			last += a[i];
		else
			last = a[i], sum++;
	}
	return sum <= m;
}

int main() {
	scanf("%d%d", &n, &m);
	int l = 0, r  = 1e9;
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		l = max(l, a[i]);
	}
	// 最大值最小
	while (l < r) {
		int mid = l + r >> 1;
		if (check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << l;
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int a[N];
int ans;

// 实现 check 函数
bool check(int x) {
	long long sum = 0;
	// 统计在 锯片高度 x 下能得到的木材的长度
	for (int i = 1; i <= n; i++)
		if (a[i] > x)
			sum += a[i] - x;
	return sum >= m * 1LL;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	int l = 0, r  = 1e9;
	// 最小值最大
	while (l < r) {
		int mid = l + r + 1 >> 1;
		if (check(mid))
			l = mid;
		else
			r = mid - 1;
	}
	cout << l;
	return 0;
}
//a - b = c
//等价于  a = b+c
//枚举  b , 得到  b 的值
//算出来 a = b+c ,
//只需要统计 有几个  a 就行了
//排序, 二分查找 a 的个数
//upper_bound - lower_bound

#include <bits/stdc++.h>
using namespace std;
long long n, a[100000000], c, ans;

int main() {
	cin >> n >> c;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	// 二分, 有序
	sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++)
		// b 的值是  a[i]
		// a 的 值是 a[i] + c
		// 找 a 的个数
		ans += upper_bound(a + 1, a + 1 + n, a[i] + c) - lower_bound(a + 1, a + n + 1, a[i] + c);
	cout << ans;
	return 0;
}

//两个函数
//查找到第一个 大于等于 查找的值的 位置
//lower_bound(查找的起始位置,查找的结束位置,查找的值)
//
//查找到第一个 大于 查找的值的 位置
//upper_bound(查找的起始位置,查找的结束位置,查找的值)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int a[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	while (m--) {
		int tmp;
		scanf("%d", &tmp);
		// 数组的起始位置,就是数组名
		int t = lower_bound(a + 1, a + 1 + n, tmp) - a;
		if (a[t] == tmp)
			printf("%d ", t);
		else
			printf("%d ", -1);
	}
	return 0;
}


最大值最小模板

while (l < r) {
	int mid = l + r >> 1;
	if (check(mid))
		r = mid;
	else
		l = mid + 1;
}

最小值最大 模板

while (l < r) {
	int mid = l + r + 1 >> 1;
	if ( check(mid) )
		l = mid;
	else
		r  = mid - 1;
}
// 单调不减:a[i]<=a[i+1]
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int a[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	while (m--) {
		int tmp;
		scanf("%d", &tmp);
		// 查询第一个大于等于 tmp 的位置
		// l r  mid 都是下标
		int l  = 1, r = n;
		// 最大值最小
		while (l < r) {   // 当循环条件退出的时候,一定是满足 l == r  的
			int mid = l + r >> 1;
			if (a[mid] >= tmp)
				r = mid;
			else
				l = mid + 1;
		}
		// 要的是刚好相等
		if (a[l] == tmp)
			printf("%d ", l);
		else
			printf("%d ", -1);
	}
	return 0;
}
Status
Done
Problem
15
Open Since
2026-2-24 0:00
Deadline
2026-3-31 23:59
Extension
24 hour(s)