前言及题解思路
第一次做二分的题,感觉还行吧(
还得多亏了祝佬在学习通上的二分代码思路才快速理解了二分QAQ),主要是得捋清思路,注意细节和精简算法
-
第一题是比较经典且基础的二分题目,可以先通过二分找到所求的数字,再继续进行二分获取该数字第一次出现的位置(我最开始做的时候找到所求的数字再用while往前推就超时了,,所以能用二分还是二分好)
这道题还可以用lower_bound,感觉像开挂一样(从各位大佬那里听说的)
-
第二题主要就是理解上的问题了,我的方法就是二分1和最大隔间的坐标,逐次判断是否符合最近距离的标准(标准的判断通过贪心实现//判断在所需最近距离的标准下能否放进所需的牛的数量),再继续二分判断出最大的最近距离
-
第三题的思路和第二题相仿,也是贪心判断标准+二分寻找答案,并且需要注意起始点这两点的特殊性,所不同的是我采用了vector数组存储,模拟出移走石头的过程,显得更直观清晰一点(其实也可以不用vector,模仿第二题解法也可)
(1)查找
代码1(二分思路)
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
int a[n+1];
a[0]=-1;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
for(int i=0; i<m; i++) {
int x;
cin>>x;
int L=1,R=n,pos=-1;
while(L<=R) {
int mid=(L+R)/2;
if(a[mid]==x){
pos=mid;
R=mid-1;
}
else if(a[mid]>x) R=mid-1;
else L=mid+1;
}
cout<<pos<<" ";
}
return 0;
}
代码2(lower_bound)
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
int a[n+1];
for(int i=1; i<=n; i++) {
cin>>a[i];
}
for(int i=0; i<m; i++) {
int x;
cin>>x;
if(a[lower_bound(a+1,a+n+1,x)-a]==x)
cout<<lower_bound(a+1,a+n+1,x)-a<<" ";
else cout<<-1<<" ";
}
return 0;
}
(2)进击的奶牛
题目
代码
#include<bits/stdc++.h>
using namespace std;
int check(int a[],int N,int C,int mid){
int sum=1,now=1;
for(int i=2;i<=N;i++){
if(a[i]-a[now]>=mid){
sum++;
now=i;
}
}
return sum>=C;
}
int main(){
int N,C;
cin>>N>>C;
int a[N+1];
a[0]=-1;
for(int i=1;i<=N;i++){
cin>>a[i];
}
sort(a+1,a+N+1);
int L=1,R=a[N],ans=0;
while(L<=R){
int mid=L+(R-L)/2;
if(check(a,N,C,mid)){
ans=mid;
L=mid+1;
}
else R=mid-1;
}
if(C==2) ans=a[N]-a[1];
cout<<ans;
return 0;
}
(3)跳石头
题目
代码
#include<bits/stdc++.h>
using namespace std;
int check(vector<int>a,int M,int mid){
int sum=0;
int temp=1;
while(temp<a.size()&&sum<=M){
if(a[temp]-a[temp-1]<mid){
sum++;
a.erase(a.begin()+temp);
}
else temp++;
}
return sum<=M;
}
int main(){
int L,N,M;
cin>>L>>N>>M;
vector<int>a;
a.push_back(0);
for(int i=1;i<=N;i++){
int a1;
cin>>a1;
a.push_back(a1);
}
a.push_back(L);
int l=1,r=L,ans=0;
while(l<=r){
int mid=l+(r-l)/2;
if(check(a,M,mid)){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans;
return 0;
}