前三道都是二分入门的模板题,直接发源代码,主要对后面4道偏难的题写题解。
1. NYOJ-2853 二分查找
二分查找的入门题,直接套模板即可。
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
int a[1200000];
int main()
{
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++)
{
cin>>a[i];
}
sort (a+1,a+n+1);
while (m--)
{
int x;
cin>>x;
int l=1,r=n;
while (l<r)
{
int mid=(l+r)/2;
if (a[mid]>=x) r=mid;
else l=mid+1;
}
if (a[l]==x){
cout<<l<<endl;
}else{
cout<<"-1"<<endl;
}
}
return 0;
}
2. NYOJ-2854 二分查找板子
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
int a[2200000];
int main()
{
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++)
{
cin>>a[i];
}
sort (a+1,a+n+1);
while (m--)
{
int x;
cin>>x;
if (a[1]>x){
cout<<"-1"<<endl;
continue;
}
if (x>a[n]){
cout<<n<<endl;
continue;
}
int l=1,r=n;
while (r-l>1)
{
int mid=(l+r)/2;
if (a[mid]<=x) l=mid;
else r=mid;
}
if (a[r]<=x) l=r;
cout<<l<<endl;
}
return 0;
}
3. NYOJ-2855 浮点二分
源代码:
#include <iostream>
using namespace std;
int main()
{
double n;
scanf ("%lf",&n);
double l=-10000,r=10000;
while (r-l>1e-6)
{
double mid=(l+r)/2;
if (mid*mid*mid<n) l=mid;
else r=mid;
}
printf ("%.6lf",l);
return 0;
}
4. CF-1886B Fear of the Dark
这题虽然标的是二分的标签,但是其实也可以不用二分。思考题面会发现总共可以分成4种情况进行。分别确保每种情况能够到达的极限值,再取这几种情况的最小值即可。
非二分方法源代码:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct fz{
double x;
double y;
};
double length(fz m,fz n)
{
return sqrt((m.x-n.x)*(m.x-n.x)+(m.y-n.y)*(m.y-n.y));
}
int main()
{
int t;
cin>>t;
while (t--)
{
fz P,A,B,O;
cin>>P.x>>P.y>>A.x>>A.y>>B.x>>B.y;
double a,b,c,d;
a=max(length(O,A),length(A,P));
b=max(length(O,B),length(B,P));
c=max({length(O,A),length(B,P),length(A,B)/2});
d=max({length(O,B),length(A,P),length(A,B)/2});
double result=min({a,b,c,d});
printf ("%.10lf\n",result);
}
return 0;
}
5. CF-1613C Poisoned Dagger
这题的关键的是在于二分时if条件的判断。因为n的范围只有100,所以我们可以遍历n,每次判断a[i]和a[i+1]的差与伤害次数的大小,再将伤害量相加与最少伤害量比较即可。
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
ll a[120];
bool check(ll mid,ll n,ll h)
{
ll sum=0;
for (int i=1;i<n;i++)
{
if (a[i+1]-a[i]<=mid) sum+=a[i+1]-a[i];
else sum+=mid;
}
sum+=mid;
if (sum>=h) return 1;
else return 0;
}
int main()
{
ll t;
cin>>t;
while (t--)
{
ll n,h;
cin>>n>>h;
for (ll i=1;i<=n;i++)
{
cin>>a[i];
}
sort (a+1,a+n+1);
ll l=1,r=h;
while (l<r)
{
ll mid=(l+r)/2;
if (check(mid,n,h)) r=mid;
else l=mid+1;
}
cout<<l<<endl;
}
return 0;
}
未完待续。。。