大致题意:
有一个人想要获得p个经验点和q元钱。现在给出n份工作,每份工作每天能得到Ai的经验值和Bi的钱,问最少需要工作多少天,
能使得总经验值>=p,总钱>=q。
先对给出的n份工作以及原点O(0,0),x轴的最大点(maxx,0),y轴最大点(0,maxy)构建凸包,根据凸组合,可知凸包上所有得点以
及凸包边上的点都可以由一天时间得到,那么只要求出射线O~P(p,q)与凸包的交点,即可求出最后的结果。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<set> 7 #include<map> 8 #include<stack> 9 #include<time.h> 10 #include<cstdlib> 11 #include<cmath> 12 #include<list> 13 using namespace std; 14 #define MAXN 200100 15 #define eps 1e-5 16 #define For(i,a,b) for(int i=a;i<=b;i++) 17 #define Fore(i,a,b) for(int i=a;i>=b;i--) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 #define mkp make_pair 21 #define pb push_back 22 #define cr clear() 23 #define sz size() 24 #define met(a,b) memset(a,b,sizeof(a)) 25 #define iossy ios::sync_with_stdio(false) 26 #define fre freopen 27 #define pi acos(-1.0) 28 #define inf 1e9+9 29 #define Vector Point 30 const int Mod=1e9+7; 31 typedef unsigned long long ull; 32 typedef long long ll; 33 typedef pair<int,int> pii; 34 typedef pair<ll,ll> pll; 35 int dcmp(double x){ 36 if(fabs(x)<=eps) return 0; 37 return x<0?-1:1; 38 } 39 struct Point { 40 double x,y; 41 int id; 42 int pre,nxt; 43 Point(double x=0,double y=0) : x(x),y(y) {} 44 Point operator - (const Point &a)const{ return Point(x-a.x,y-a.y); } 45 Point operator + (const Point &a)const{ return Point(x+a.x,y+a.y); } 46 Point operator * (const double &a)const{ return Point(x*a,y*a); } 47 Point operator / (const double &a)const{ return Point(x/a,y/a); } 48 bool operator < (const Point &a)const{ if(x==a.x) return y<a.y;return x<a.x; } 49 bool operator == (const Point &a)const{ return dcmp(x-a.x)==0 && dcmp(y-a.y)==0; } 50 void read(int iid=0) { scanf("%lf%lf",&x,&y);id=iid; } 51 void out(){cout<<"Bug: "<<x<<" "<<y<<endl;} 52 }; 53 inline double Cross(Vector a,Vector b) { return a.x*b.y-a.y*b.x; } 54 inline double Dot(Vector a,Vector b) { return a.x*b.x+a.y*b.y; } 55 inline double dis(Vector a) { return sqrt(Dot(a,a)); } 56 int ConvexHull(Point *p,int n,Point *ch){ 57 int m=0; 58 sort(p,p+n); 59 For(i,0,n-1){ 60 p[i].id=i; 61 while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 62 ch[m++]=p[i]; 63 } 64 int k=m; 65 Fore(i,n-2,0){ 66 while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 67 ch[m++]=p[i]; 68 } 69 if(n>1) m--; 70 return m; 71 } 72 inline bool Onsegment(Point a,Point b1,Point b2){ 73 return dcmp(Cross(b1-a,b2-a))==0 && dcmp(Dot(b1-a,b2-a))<0; 74 } 75 bool Intersect_Segm_Ray(Point a1,Vector u,Point b1,Point b2){ 76 double c1=Cross(b1-a1,u),c2=Cross(b2-a1,u); 77 if(dcmp(c2)*dcmp(c1)>0) return 0; 78 if(dcmp(c2)*dcmp(c1)<0){ 79 c1=Dot(b1-a1,u);c2=Dot(b2-a1,u); 80 return dcmp(c1)>=0 && dcmp(c2)>=0; 81 } 82 if(c1==0) return dcmp(Dot(b1-a1,u))>0; 83 if(c2==0) return dcmp(Dot(b2-a1,u))>0; 84 } 85 Point Intersect_Line_Point(Point p,Vector u,Point q,Vector v){ 86 Vector w=p-q; 87 double t=Cross(v,w)/Cross(u,v); 88 return p+u*t; 89 } 90 int n; 91 double maxx,maxy; 92 Point p[MAXN],cp; 93 Point ch[MAXN]; 94 int solve(){ 95 double ans=inf;maxx=0;maxy=0; 96 cin>>n;cp.read(); 97 For(i,0,n-1) p[i].read(),maxx=max(p[i].x,maxx),maxy=max(p[i].y,maxy); 98 p[n]=Point(0,0); 99 p[n+1]=Point(0,maxy); 100 p[n+2]=Point(maxx,0); 101 int m=ConvexHull(p,n+3,ch); 102 For(i,0,m-1){ 103 if(ch[i]==Point(0,0) || ch[(i+1)%m]==Point(0,0)) continue; 104 if(Intersect_Segm_Ray(Point(0,0),cp,ch[(i+1)%m],ch[i])){ 105 Point st=Intersect_Line_Point(cp,cp,ch[i],ch[(i+1)%m]-ch[i]); 106 ans=min(ans,dis(cp)/dis(st)); 107 } 108 } 109 printf("%.15lf\n",ans); 110 } 111 int main(){ 112 // fre("in.txt","r",stdin); 113 int t=1; 114 while(t--)solve(); 115 return 0; 116 }