题目链接:(https://vjudge.net/contest/368387#problem)
**
二分答案其实就是在已知条件下又增加了一个条件
**
二分答案的基本思路,对所求数值的所在范围进行二分查找,对特定数值进行判断是否符合要求。
但是难点在于f(x)函数,要根据题目来写。
A - 二分(经典题)(*)(最大化最小值)
fun函数内贪心判断,设两个指针,找到最近的前面的不小于后面的位置坐标,,M-1头牛全部找到即可。
#include <iostream>
#include<algorithm>
using namespace std;
int n,c;
int a[100005];
bool fun(int x){
int t1=0;
for(int i=1;i<c;i++){
int t2=t1+1;
while(t2<n&&a[t2]-a[t1]<x){//在有解范围内没找到解
t2++;
}
if(t2==n){
return false;
}
t1=t2//找到的话进行位置的更新
return true;
}
int main()
{
cin>>n>>c;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int minn=0,maxx=a[n-1],mid;
while(maxx-minn>1){
mid=(maxx+minn)/2;
if(fun(mid))
minn=mid;
else
maxx=mid;
}
cout<<minn<<endl;
return 0;
}
B - 二分(*)
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
char a[200005],b[200005];
int del[200005],vis[200005];
int la,lb;
int fun(int mid){
memset(vis,0,sizeof(vis));
for(int i=0;i<=mid;i++){
vis[del[i]-1]=1;
}
int now=0;
for(int i=0;i<la;i++){
if(vis[i]==0){
if(a[i]==b[now]){
now++;
}
}
}
if(now==lb) return 1;
else return 0;
}
int main()
{
cin>>a;
cin>>b;
la=strlen(a);lb=strlen(b);
for(int i=0;i<la;i++){
cin>>del[i];
}
int ans=-1,l=0,r=la-1;
while(r-l>=0){
int mid=(l+r)/2;
if(fun(mid)==1){
l=mid+1;
ans=mid;
}
else{
r=mid-1;
}
}
cout<<ans+1<<endl;
return 0;
}
D - Snowball
直接模拟一遍
#include <iostream>
using namespace std;
int main()
{
int w,h,u1,d1,u2,d2;
cin>>w>>h>>u1>>d1>>u2>>d2;
for(int i=h;i>0;i--){
w+=i;
if(i==d1)
w-=u1;
else if(i==d2)
w-=u2;
if(w<0)
w=0;
}
cout<<w<<endl;
return 0;
}
E - Squares and Segments
长与宽越接近,可以使得面积最大,长与宽的和最小。
所以比较长宽的大小,小的那个进行加一处理。
#include <iostream>
using namespace std;
int n,w=1,h=1;
int main()
{
cin>>n;
while(w*h<n){
if(w<h)
w++;
else
h++;
}
cout<<w+h<<endl;
return 0;
}