基础算法训练题单之二分(从入门到入土)
A 【深基13.例1】查找
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, t;
int q[N];
int serch(int x) {
int l = 0, r = n+1;
while (l + 1 < r) {
int mid = l + r >> 1;
if (q[mid] < x) l = mid;
else r = mid;
//printf("%d %d\n",l,r);
}
if (q[r] != x) return -1;
else return r;
}
signed main(){
import;
cin >> n >> t;
for (int i = 1; i <= n; ++i) cin >> q[i];
while (t--) {
int x; cin >> x;
int idx = serch(x);
printf("%d ", idx);
}
return 0;
}
B, A-B 数对
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
LL n, c;
LL q[N];
int serch1(int x) {
int l = -1, r = n;
while (l + 1 < r) {
int mid = l + r >> 1;
if (q[mid] < x) l = mid;
else r = mid;
}
if (q[r] != x) return -1;
else return r;
}
int serch2(int x) {
int l = -1, r = n;
while (l + 1 < r) {
int mid = l + r >> 1;
if (q[mid] > x) r = mid;
else l = mid;
}
if (q[l] != x) return -1;
else return l;
}
signed main(){
import;
cin >> n >> c;
LL ans = 0;
for (int i = 0; i < n; ++i) cin >> q[i];
sort(q, q + n);
for (int i = 0; i < n; ++i) {
LL x = q[i] + c;
LL idx1 = serch1(x);
LL idx2 = serch2(x);
if (idx1 != -1) {
if (idx1 == idx2) ans++;
else ans += idx2 - idx1 + 1;
}
}
cout << ans << endl;
return 0;
}
C [COCI 2011/2012 #5] EKO / 砍树
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
LL n, x,ans;
LL q[N];
LL check(LL mid) {
LL sum = 0;
for (int i = 1; i <= n; ++i) {
sum += max(0LL, q[i] - mid);
}
if (sum >= x) return 1;
else return 0;
}
signed main() {
import;
scanf("%lld %lld", &n, &x);
LL heightest = 0;
for (int i = 1; i <= n; ++i)
{
scanf("%lld", &q[i]);
heightest = max(heightest, q[i]);
}
LL l = 0, r = heightest + 1;
while (l + 1 < r) {
LL mid = l + r >> 1;
if (check(mid)) l = mid;
else r = mid;
}
printf("%lld", l);
return 0;
}
D [NOIP2001 提高组] 一元三次方程求解
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
double a, b, c, d;
double l, r;
double fun(double x) {
return a * x * x * x + b * x * x + c * x + d;
}
signed main() {
import;
cin >> a >> b >> c >> d;
int sum = 0;
for (int i = -100; i < 100; ++i) {
l = i, r = i + 1;
if (fun(l)==0) {
printf("%.2lf ", l);
sum++;
continue;
}
if (fun(l) * fun(r) < 0) {
while (r - l > 0.001) {
double mid = (l + r) / 2;
if (fun(l) * fun(mid) < 0) r = mid;
else l = mid;
}
printf("%.2lf ", r);
sum++;
}
if (sum == 3) break;
}
return 0;
}
E 烦恼的高考志愿
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, m;
int q[N];
signed main() {
import;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> q[i];
sort(q + 1, q + n + 1);
LL sum = 0;
for (int i = 0; i < m; ++i) {
int x; cin >> x;
int l = 1, r = n;
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (q[mid]<=x) l = mid;
else r = mid;
}
sum += min(abs(q[l] - x), abs(q[r] - x));
}
cout << sum << endl;
return 0;
}
F 木材加工
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, x;
int q[N];
bool check(int mid) {
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum += q[i] / mid;
if (sum >= x) return true;
}
return false;
}
signed main() {
import;
cin >> n >> x;
int heightest = 0;
for (int i = 1; i <= n; ++i) {
cin >> q[i];
heightest = max(heightest, q[i]);
}
int l = 0, r = heightest + 1;
while (l + 1 < r) {
int mid = l + r >> 1;
if (check(mid)) l = mid;
else r = mid;
}
cout << l << endl;
return 0;
}
G [NOIP2015 提高组]跳石头
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int d,n, m;
int q[N];
bool check(int x) {
int cnt = 0;
int now = 0;
for (int i = 1; i <= n+1;++i) {
if (q[i] - q[now] < x) {
cnt++;
}
else {
now = i;
}
}
if (cnt <= m) return true;
else return false;
}
signed main() {
import;
cin >> d >> n >> m;
for (int i = 1; i <= n; ++i) cin >> q[i];
q[n + 1] = d;
int l = 0, r = d + 1;
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) l = mid;
else r = mid;
}
cout << l << endl;
return 0;
}
H [TJOI2007] 路标设置
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int d, n, m;
int q[N], p[N];
bool check(int x) {
int cnt = 0; //记录操作次数
int now = 0; //当前的位置
// i 为要跳跃的位置
for (int i = 1; i <= n + 1; i++) {
if (p[i] > x) { //如果距离大于二分值,则要插入路标使得距离变小
int num = p[i] - x;
cnt++; //操作次数加一
while (num > x) { //记录操作次数,使得距离小于二分值
num -= x;
cnt++;
}
}
else {
now = i; //小于等于二分值就直接跳过
}
}
if (cnt <= m) return true; //操作次数小于等于m,说明操作次数少了,最小空旷指数不是最小的,r = mid,即下次二分距离变小
else return false; //操作次数大于m,不符合,则需要将最小空旷指数往上调大,l = mid,即下次二分距离变大
}
signed main() {
import;
cin >> d >> n >> m; //公路的长度,原有路标的数量,以及最多可增设的路标数量
for (int i = 1; i <= n; ++i) {
cin >> q[i];
p[i] = q[i] - q[i - 1]; //p数组记录相邻两个路标的距离
}
q[n + 1] = d; //将最后一个路标加入数组
p[n + 1] = q[n + 1] - q[n]; //最后一个与终点的距离
int l = 0, r = d + 1; //二分答案
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid; //说明操作次数少了,换句话说,是最小空旷指数比较大,还可以小
else l = mid; //这个则是操作次数多了了,不符合
}
//这里有个方法,如果你分不清边界,就去检查一下再输出,实际这题输出 r
if (check(r)) cout << r << endl;
else cout << l << endl;
return 0;
}
I 数列分段 Section II
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, m;
int q[N], p[N];
bool check(int x) {
int cnt = 1;
int sum = 0;
for (int i = 0; i < n; ++i) {
if (sum + q[i] <= x ) {
sum += q[i];
}
else {
sum = q[i];
cnt++;
}
}
return cnt <= m ;
}
signed main() {
import;
cin >> n >> m;
int l = 0, r = 0;
for (int i = 0; i < n; ++i) {
cin >> q[i];
l = max(l, q[i]);
r += q[i];
}
while (l < r) //二分模板
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1 ;
}
cout << r << endl;
return 0;
}
J 银行贷款
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
double w,pay,month;
int q[N], p[N];
bool check(double x) {
double t = w;
for (int i = 0; i < month; ++i) {
t = t * (1 + x) - pay;
}
if (t <= 0) return true;
else return false;
}
signed main() {
import;
cin >> w >> pay >> month;
double l = 0, r = 5;
while (r - l > 0.0001) {
double mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid;
}
printf("%.1lf", l*100);
return 0;
}
K 小鸟的设备
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
double n, p, a[N], b[N];
bool check(double mid)
{
double sum = 0;
for (int i = 1; i <= n; i++) {
if (a[i] * mid > b[i])
sum += a[i] * mid - b[i];
}
return sum <= p * mid;
}
signed main() {
cin >> n >> p;
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i];
double tmp = 0;
for (int i = 1; i <= n; i++) {
tmp += a[i];
}
if (tmp <= p) {
cout << "-1";
return 0;
}
double l = 0, r = 1e10 + 1;
while (r - l >= 0.00001) {
double mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid;
}
cout << l << endl;
return 0;
}

浙公网安备 33010602011771号