FZU ACM 寒假第二讲:二分法
二分法
1.while(l<=r)
int bsearch_1(int l, int r)
{
int res=0x3f3f3f3f//可以先将res设置为一个很大的数,如果while循环终止后res没变,便没找到
while (l <= r)
{
int mid = l + r >> 1;//或写成(l+r)/2
if (a[mid]>=x){
r = mid-1;
res=mid;
}
else l = mid + 1;
}
return res;
}
2.while(l<r)
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;//或写成(l+r)/2
if (a[mid]>=x) r = mid;
else l = mid + 1;
}
return l;//因为while循环当l==r时终止,return r也可以
}
1.二分查找
思路:函数二分查找
include
using namespace std;
int binarySearch(int arr[], int n, int target) {
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return 1; // 找到返回1
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return 0; // 没找到返回0
}
int main() {
int n;
cin>>n;
int s[n];
for(int i=0;i<n;i++){
cin>>s[i];
}
int q;
cin>>q;
int b;
for(int i=0;i<q;i++){
cin>>b;
if(binarySearch(s,n,b)==1){
cout<<"YES"<<endl;
}else cout<<"NO"<<endl;
}
return 0;
}
2.A-B数对
思路:循环B,A=B+C,找A二分法找头尾
include
include
using namespace std;
const int N=200010;
long long a[N],n,c,res,st;
int main(){
cin>>n>>c;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<n;i++)
{
int l=i+1,r=n;
while(l<r)
{
int mid=l+r>>1;
if(a[mid]-a[i]>=c) r=mid;
else l=mid+1;
}
if(a[l]-a[i]==c) st=l;
else continue;
l=st-1,r=n;
while(l<r)
{
int mid=l+r+1>>1;
if(a[mid]<=a[st]) l=mid;
else r=mid-1;
}
res+=l-st+1;
}
cout<<res;
return 0;
}
3.分巧克力
思路:K=(宽度/mid)*(长度/密度)
include <stdio.h>
int canCut(int N, int K, int H[], int W[], int len) {
int count = 0;
for (int i = 0; i < N; i++) {
count += (H[i] / len) * (W[i] / len);
if (count >= K) {
return 1;
}
}
return 0;
}
int main() {
int N, K;
scanf("%d %d", &N, &K);
int H[N], W[N];
for (int i = 0; i < N; i++) {
scanf("%d %d", &H[i], &W[i]);
}
int left = 1, right = 100000;
int ans = 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (canCut(N, K, H, W, mid)) {
ans = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
printf("%d\n", ans);
return 0;
}
4.卡牌
思路:通过mid,找到缺少卡牌的数,判断空白卡牌是否够用
include <bits/stdc++.h>
using namespace std;
const int MAX_N =21e5+10;
int a[MAX_N];
int b[MAX_N];
int n;
long long m;
bool canMake(int mid) {
long long need = 0;
for (long long i = 1; i <= n; ++i) {
if (mid-a[i]<=b[i]) {
need+=max(mid-a[i],0);
}else{
return 0;
}
}
if(need<=m){
return 1;
}return 0;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
for (int i = 1; i <= n; ++i) {
cin >> b[i];
}
int left = 1, right = nn;
int ans = 0;
while (left <= right) {
int mid =left+right>>1;
if (canMake(mid))
{
ans = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
cout << ans << endl;
return 0;
}

浙公网安备 33010602011771号