c++专题二

c++专题二学习日记

二分法

1.基本模版

(1)l<=r
int l,r,ans;

while(l<=r){

	int mid=l+r >> 1;

	if(check(mid)) ans=mid,l=mid+1;

	else  r=mid-1;

}

return ans;
(2)l<r
int l,r;

while(l<r){

	int mid=l+r+1 >>1;

	if(check(mid)) l=mid;

	else  r=mid-1;

}

return l;

or

while(l<r){

	int mid=l+r-1 >>1;

	if(check(mid))r=mid;

	else  l=mid+1;

}

return r;

2.做题

(1)A-B数对


应该用二分查找符合A=B+C的A,不过我用了map就不改了

int main(){
	int n,c;
	cin>>n>>c;
	unordered_map<int,int> numbers;
	long long count=0;
	vector<int> a(n);
	int i;
	for(i=0;i<n;i++){
		cin>>a[i];
		numbers[a[i]+c]+=1;
	}
	sort(a.begin(),a.end());    //用algorithm中的sort排序数组a
	for(i=0;i<n;i++){
		count+=numbers[a[i]];
	}
cout<<count<<endl;

return 0;
}
(2)抄书


思路:

[1]用贪心算法来check找到的mid可不可行(第1个人抄,抄到超过mid后换下一个人抄,以此类推;

[2]用二分找到mid;

[3]因为要让前面的人少抄,贪心要从后往前走

#include<iostream>
using namespace std;
const int K=500;
int m,k,mid;
int a[K+10],s[K+10],ed[K+10];
bool check(int mid){           //[1]
	int cnt=1,now=mid;
	int i;
	for(i=1;i<=m;i++){
		if(a[i]>now){
			cnt++;
			i--;
			now=mid;
		}
		else
			now-=a[i];
	}
	return cnt<=k;
}
int main(){
	cin>>m>>k;
	int i,max=0,sum=0;
	for(i=1;i<=m;i++){
		cin>>a[i];
		if(a[i]>max)max=a[i];
		sum+=a[i];
	}
	int l=max,r=sum;
	while(l<r){                   //[2]
		mid=(l+r-1) >> 1;
		if(check(mid)){
			r=mid;
		}
		else
			l=mid+1;
	}
	ed[k]=m;
	s[1]=1;
	int j,now=r;                  //[3]
	for(i=k,j=m;i>0;i--){
		for(;now>=a[j]&&j>0;j--){
			now-=a[j];
		}
			s[i]=j+1;
			ed[i-1]=j;
			now=r;
		

	}
	for(i=1;i<=k;i++){
		cout<<s[i]<<' '<<ed[i]<<endl;
	}
	return 0;

}
(3)青蛙过河

思路:

假设青蛙跳跃长度为y,那么对任意一个区间[l,l+y-1],高度和一定大于2x。如果每段高度和都大于2x,那么对于0~n的任意一点a,都有大于等于2x种途径跳上a,所以只要保证任意一段长度为y的区间,高度和大于2x,青蛙跳跃能力为y时就可以上岸。

#include<iostream>
using namespace std;
const int N=100005;
int n,x;
int h[N];
long long s[N];
int l,r,mid;
bool check(int mid){
	int i;
	for(i=0;i+mid-1<n;i++){
		int j=i+mid-1;
		if(s[j]-s[i-1]<2*x)
			return false;
	}
	return true;
}
int main(){								//前缀和:
	cin>>n>>x;							  sum[1]=h[1]
	int i;								  sum[2]=h[1]+h[2]
	for(i=1;i<n;i++){					  sum[3]=h[1]+h[2]+h[3]...
		cin>>h[i];						
		s[i]=s[i-1]+h[i];				  [L,R]=sum[R]-sum[L-1]
	}
	l=1;
	r=n;
	while(l<r){
		mid=l+r >> 1;
		if(check(mid))
			r=mid;
		else
			l=mid+1;
	}
	cout<<l<<endl;
	
	return 0;
}
posted @ 2025-01-26 18:26  佘雅晴  阅读(4)  评论(0编辑  收藏  举报