第一次写三分
三分的基本模板
int SanFen(int l,int r) //找凸点 { while(r-l>1) { //mid为中点,midmid为四等分点 int mid = (l+r)/2; int midmid = (mid+r)/2; if( f(mid) > f(midmid) ) r = midmid; else l = mid; } return f(l) > f(r) ? l : r; }
这道题里面任意两点的距离都可以看作是一个凹函数,对任意t对所有凹函数取最大值构成一个新的凹函数,求新函数的最小值
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=305; const double eps=1e-8; int T,n; double tim,mindis; struct point { double x,y; int dx,dy; }p[N]; double dist(point p1,point p2,double t) { double x2=(p1.x+t*p1.dx-p2.x-t*p2.dx)*(p1.x+t*p1.dx-p2.x-t*p2.dx); double y2=(p1.y+t*p1.dy-p2.y-t*p2.dy)*(p1.y+t*p1.dy-p2.y-t*p2.dy); return sqrt(x2+y2); } double cal(double x) { double ret=-1; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) ret=max(ret,dist(p[i],p[j],x)); return ret; } void solve() { double l=0,r=1e8; while(r-l>eps) { double mid=(l+r)/2; double midmid=(mid+r)/2; double ans1=cal(mid); double ans2=cal(midmid); if(ans1>ans2) l=mid; else r=midmid; } tim=l; mindis=cal(tim); } int main() { scanf("%d",&T); for(int kase=1;kase<=T;kase++) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lf%lf%d%d",&p[i].x,&p[i].y,&p[i].dx,&p[i].dy); solve(); printf("Case #%d: %.2lf %.2lf ",kase,tim,mindis); } }