BZOJ 4880

      这道题我们这样考虑,对于1号手机的两个属性X1和Y1,和其他手机的两个属性X2和Y2,如果有W1*X1+W2*Y1>=W1*X2+W2*Y2,那么1号手机就优于2号手机,这样我们进行移项,可以根据X1和X2的大小关系讨论出两种情况:(Y2-Y1)/(X1-X2)<=W1/W2 ,(Y2-Y1)/(X1-X2)>=W1/W2 。对于X1=X2的情况,我们是可以讨论出谁更优的,这样我们就发现问题转化成了在一些斜率中确定一个斜率,使得满足上述条件的数目最多或最少,我们可以证明最优的斜率一定是这些斜率中的一个,这样我们就可以对斜率排序,然后枚举一下,就可以计算了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define maxn 100005
 6 struct Vergil
 7 {
 8     int x,y;
 9     bool operator < (const Vergil &a) const 
10     {
11         bool pd=((x<0)^(a.x<0));
12         return pd?y*a.x>x*a.y:y*a.x<x*a.y;
13     }
14 }k1[maxn],k2[maxn];
15 int n,X,Y,tot1,tot2,L1,L2,ans1,ans2,cur1[2],cur2[2];
16 
17 inline int read(void)
18 {
19     int x=0;
20     char ch=getchar();
21     while (ch>'9'||ch<'0') ch=getchar();
22     while (ch>='0'&&ch<='9')
23     {
24         x=x*10+ch-'0';
25         ch=getchar();
26     }
27     return x;
28 }
29 
30 int main()
31 {
32     n=read()-1;X=read();Y=read();
33     for (int i=1;i<=n;i++) 
34     {
35         int x=read(),y=read();
36         if (x<X) k1[++tot1]=(Vergil){X-x,y-Y};
37         if (x>X) k2[++tot2]=(Vergil){X-x,y-Y};
38         if (x==X)
39         {
40             if (y<Y) L1++,L2++;
41             if (y==Y) L1++;
42         }
43         cur1[0]+= x<=X;
44         cur1[1]+= x<X;
45         cur2[0]+= y<=Y;
46         cur2[1]+= y<Y;
47     }
48     sort(k1+1,k1+tot1+1);
49     sort(k2+1,k2+tot2+1);
50     ans1=0;ans2=n+4;
51     for (int i=1;i<=tot1;i++) 
52     {
53         if (k1[i].x*k1[i].y<0) continue;
54         int a=i-1,b=i;
55         int p1=lower_bound(k2+1,k2+tot2+1,k1[i])-k2;
56         int p2=upper_bound(k2+1,k2+tot2+1,k1[i])-k2;
57         a+=(tot2-p2+1);b+=(tot2-p1+1);
58         ans1=max(ans1,b);
59         ans2=min(ans2,a);
60     }
61     for (int i=1;i<=tot2;i++) 
62     {
63         if (k2[i].x*k2[i].y<0) continue;
64         int a=tot2-i,b=tot2-i+1;
65         int p1=lower_bound(k1+1,k1+tot1+1,k2[i])-k1;
66         int p2=upper_bound(k1+1,k1+tot1+1,k2[i])-k1;
67         a+=(p1-1);b+=(p2-1);
68         ans1=max(ans1,b);
69         ans2=min(ans2,a);
70     }
71     ans1+=L1;ans2+=L2;
72     ans1=max(ans1,max(cur1[0],cur2[0]));
73     ans2=min(ans2,min(cur1[1],cur2[1]));
74     printf("%d %d\n",n+1-ans1,n+1-ans2);
75     return 0;
76 }
原文地址:https://www.cnblogs.com/lvyouyw/p/6856291.html