01:查找最接近的元素
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 100004
using namespace std;
int t[MAX];
int main()
{
int n;cin>>n;
for(int i=0;i<n;++i)cin>>t[i];
int m,a,low=0,high=n-1,f;cin>>m;
for(int i=0;i<m;++i)
{
cin>>a;
low=0,high=n-1,f=1;
if(a<=t[low]){ cout<<t[low]<<endl;continue; }
if(a>=t[high]){ cout<<t[high]<<endl;continue; }
while(low<=high)
{
int mid=(low+high)/2;
if(t[mid]<a) low=mid+1;
else high=mid-1;
}
f = (abs(t[low]-a) < abs(t[high]-a)) ? low : high;
cout<<t[f]<<endl;
}
return 0;
}
02:二分法求函数的零点
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 100004
using namespace std;
double t[6][2]={{1,5},{-15,4},{85,3},{-225,2},{274,1},{-121,0}};
double f(double x)
{
return pow(x,5)-15.0*pow(x,4)+85.0*pow(x,3)-225.0*pow(x,2)+274.0*x-121.0;
}
int main()
{
double low=1.5,high=2.4, mid;
while(fabs(low-high)>1e-15)
{
mid=(low+high)/2.0;
double re=f(mid);
if(re>0) low=mid;
else high=mid;
}
printf("%.6lf",mid);
return 0;
}
03:矩形分割
【降维,终于知错了if(Check(kk))与if(Check(kk)>0)是不一样的,一个是非0一个是大于0】
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
int a[MAX];
int r,n,k,L,T, W, H;
long long Check(int k)
{
long long c=0,b=0;
for(int i=0;i<k;++i) c+=a[i];
for(int i=k;i<r;++i) b+=a[i];
return c-b;
}
int main()
{
scanf("%d%d",&r,&n);
for(int i=0;i<n;++i)
{
scanf("%d%d%d%d",&L,&T,&W,&H);
for(int i=L;i<L+W;++i) a[i]+=H;
}
int low=0,high=r;
while(low+3<high)
{
int kk=(low+high)/2;
if(Check(kk)>0) high=kk;
else low=kk;
}
long long su=0x3f3f3f3f;
for(int i=high;i>=low;--i)
{
long long m=Check(i);
if(m<su&&m>=0)
{
su=m;k=i;
}
}
while(a[k]==0&&k<r)k++;
printf("%d",k);
return 0;
}
04:网线主管
【可烦死这种求精度的了,long long的精度比int高,自己用整形取上整提精度】
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
double x;
long long a[MAX],t,sum,z,mid;
int n,k;
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;++i)
{
scanf("%lf",&x);
a[i]=int(x*100.00+0.5);//提炼一下精度
z = z > a[i] ? z : a[i];
sum+=a[i];
}
int low = z/k;//最小长度
int high= sum/k;//最大长度
while(low<high)
{
mid=(low+high+1)/2,t=0;
for(int i=0;i<n;++i) t+=int(a[i]/mid);
if(t>=k)low=mid;
else high=mid-1;
}
printf("%.2lf",low/100.00);
}
05:派
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
double x;
double a[MAX],sum,z,mid;
int n,k,t;//保存每一个派的体积
double f(double r)
{
return r*r*3.1415926535897932;
}
int main()
{
scanf("%d%d",&n,&k);k++;
for(int i=0;i<n;++i)
{
scanf("%lf",&x);
a[i]=f(x);
z = z > a[i] ? z : a[i]; //找体积最大的
}
double low = 0,high=z;
while(low<=high)
{
mid=(low+high)/2,t=0;
for(int i=0;i<n;++i) t+=int(a[i]/mid);
if(t>=k)low=mid+0.000001;
else high=mid-0.000001;
}
printf("%.3lf",mid);
}
06:月度开销
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
int a[MAX],t,mid;
int n,m,low = 0,high=0;
int f(int mid)
{
int count=1,i,temp=0;
for(i=0;i<n;i++)
{
if(temp+a[i]<=mid) temp+=a[i];
else if(a[i]<=mid)
{
count++;
temp=a[i];
if(count>m) return -1;
}
else return -1;
}
if(count>m) return -1;
else if(count<=m) return 1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
{
scanf("%d",&a[i]);
low = low > a[i] ? low : a[i];
high+=a[i];
}
while(low<high)
{
mid=(low+high)/2,t=f(mid);
if(t==-1)low=mid+1;
else high=mid;
// cout<<low<<"_"<<mid<<"_"<<high<<endl;
}
printf("%d",low);
}
07:和为给定数
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
int a[MAX],t,mid,flag=1;
int n,m,low = 0,high=0;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;++i)scanf("%d",&a[i]);
scanf("%d",&m);
sort(a,a+n);
for(int i=0;i<n;++i)//小值
{
low=i+1,high=n-1;
while(low<=high)//大值
{
mid=(low+high)>>1;
if(a[mid]+a[i]<m){ low=mid+1; }
else if(a[mid]+a[i]>m) { high=mid-1; }
else { printf("%d %d",a[i],a[mid]);flag=0;goto stop; }
}
}
stop:if(flag)
{
cout<<"No";
}return 0;
}
08:不重复地输出数
【不知道二分在哪里】
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
int a[MAX],t,mid,flag=1;
int n,m,low = 0,high=0;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;++i)scanf("%d",&a[i]);
sort(a,a+n);
for(int i=0;i<n;++i)//小值
{
if(a[i]!=a[i+1]) cout<<a[i]<<" ";
}
return 0;
}
09:膨胀的木棍
【数学公式能化简化简,把三角函数的都化到最简单,不然精度上不去】
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 1000005
using namespace std;
double L,n,C,low=0,high,mid;
int main()
{
scanf("%lf%lf%lf",&L,&n,&C);
if(L<1e-14)
{
printf("0.000");
return 0;
}
double LL=(1+n*C)*L;
high=asin(1.0);//90°
while(high-low>1e-14)
{
mid = (low+high)/2;
if( LL * sin(mid)/mid <= L ) high=mid;
else low=mid;
}
printf("%.3lf",L/2*tan(mid/2));
return 0;
}
10:河中跳房子
#include<iostream>
#include<algorithm>
#include<cmath>
#define MAX 50010
using namespace std;
int L,N,M,s[MAX];
bool f(int mid)
{
int bp=0,leaf=0;
for(int sp=1;sp<=N+1;++sp)
{
if(s[sp]-s[bp]>=mid){ leaf++;bp=sp; }
}
if(leaf>N-M)return true;
else return false;
}
int main()
{
scanf("%d%d%d",&L,&N,&M);
for(int i=1;i<=N;++i)scanf("%d",&s[i]);s[N+1]=L;
int low=1,heigh=L,ans=0;
while(low<=heigh)
{
int mid=(low+heigh)/2;
if(f(mid)) { ans=mid;low=mid+1; }
else { heigh=mid-1; }
}
printf("%d",ans);
return 0;
}