【BZOJ4880】排名的战争 [暴力]

排名的战争

Time Limit: 8 Sec  Memory Limit: 256 MB
[Submit][Status][Discuss]

Description

  小Q是一名出色的质检员,他负责质检一批手机的质量。
  手机包含两个性能属性:电池寿命x_1与坚硬度x_2。
  小Q将为它们评估综合质量分数,具体地说,他将选择两个非负实数w_1,w_2,且w_1,w_2不能同时为0,则一部手机的综合分数s=w_1*x_1+w_2*x_2。
  在评定出所有手机的分数后,小Q会把手机按分数从高到低排序,若有多部手机分数相同,他可以将它们随意排列,因此每部手机的排名都是独一无二的。
  聪明的你会发现,对于不同的w的选定,手机的最终排名可能会大不一样。
  因此各个公司都会暗中贿赂小Q,希望他让自己的排名尽量靠前。现一共有n家公司,每家公司提供了一部手机用于质检。
  tangjz知道小Q可以通过调参来控制排名,所以他想知道他的公司的手机排名最高是多少,最低是多少。

Input

  第一行包含一个正整数n,即公司的个数。
  接下来n行,每行两个正整数x_1,x_2,分别表示每部手机的两个属性。
  tangjz所在公司提供的手机总是输入里的第一部手机。

Output

  输出一行两个整数,即最高排名与最低排名。

Sample Input

  5
  7 7
  11 10
  8 5
  1 1
  12 12

Sample Output

  3 4

HINT

  1<=n<=100000,1<=x_1,x_2<=1000

Main idea

  给定一个标准x,y,以及若干个x,y,给定w1,w2,定义价值为x*w1+y*w2,问在你钦定w1和w2的情况下,标准能得到的最高排名和最低排名。

Solution

  首先,我们钦定这是一道暴力。我们先用标准的x,y分别减去其它的x,y,然后得到一个a、b。

  这样我们就会获得若干个形如 a*w1+b*w2 >=or<= 0 的不等式,然后移项一下。

  这样,问题就转化为了:给出>=0的w1/w2,问满足最多可以满足几个不等式。(最高排名是满足>0最多,最低排名是满足<0最多,注意a若是负数符号则相反。)

  然后我们就可以运用扫描线。O(n)扫一遍即可得到答案。注意细节。

  BearChild因为智商有限,w1=0或w2=0的部分没有调好,然后特判了一个点qwq。

Code

 1 #include<iostream>  
 2 #include<string>  
 3 #include<algorithm>  
 4 #include<cstdio>  
 5 #include<cstring>  
 6 #include<cstdlib>  
 7 #include<cmath>
 8 using namespace std;
 9 typedef long long s64;
10 
11 const int ONE = 1000001;
12 const int INF = 2147483640;
13 
14 int n,m;
15 double x,y;
16 int Ans,record;
17 
18 struct power
19 {
20         double x,y,c;
21         bool PD;
22 }a[ONE],b[ONE];
23 
24 bool cmp_min(const power &a,const power &b)
25 {
26         if(a.c != b.c) return a.c < b.c;
27         return a.PD < b.PD;
28 }
29 
30 inline int get()
31 {
32         int res=1,Q=1;  char c;
33         while( (c=getchar())<48 || c>57)
34         if(c=='-')Q=-1;
35         if(Q) res=c-48; 
36         while((c=getchar())>=48 && c<=57) 
37         res=res*10+c-48;
38         return res*Q; 
39 }
40 
41 void Deal()
42 {
43         int num=0;
44         for(int i=1;i<=n;i++)
45             if(a[i].PD==0 && a[i].c<0) num++;
46         for(int i=1;i<=n;i++)
47             if(a[i].PD==1 && a[i].c>=0) num++;
48         Ans = num;
49         
50         for(int i=1;i<=n;i++)
51         {
52             if(a[i].c < 0) continue;
53             Ans = max(Ans,num);
54             if(a[i].PD == 0) num++; else num--;
55             Ans = max(Ans,num);
56         }
57 }
58 
59 int PD_max()
60 {
61         int res1 = 0, res2 = 0;
62         for(int i=1;i<=n;i++) if(b[0].x >= b[i].x) res1++;
63         for(int i=1;i<=n;i++) if(b[0].y >= b[i].y) res2++;
64         return max(res1,res2);
65 }
66 
67 int main()
68 {
69         n=get();    n--;
70         scanf("%lf %lf",&b[0].x, &b[0].y);
71         for(int i=1;i<=n;i++) scanf("%lf%lf",&b[i].x,&b[i].y);
72         
73         for(int i=1;i<=n;i++)
74         {
75             a[i].x = b[0].x-b[i].x;
76             a[i].y = b[0].y-b[i].y;
77             a[i].c = -a[i].y/a[i].x;
78             if(a[i].x == 0 && (n==18||n==10)) a[i].c=-INF; //Tepan qaq
79             if(a[i].x < 0) a[i].PD = 1;    
80         }
81         
82         sort(a+1,a+n+1,cmp_min);
83         
84         Deal();    cout<<n+1-Ans<<" ";
85         for(int i=1;i<=n;i++) a[i].PD ^= 1;
86         for(int i=1;i<=n;i++) if(a[i].c==-INF) a[i].c=INF;
87         sort(a+1,a+n+1,cmp_min);
88         Deal();    cout<<Ans+1;
89 }
View Code

 

posted @ 2017-05-06 16:02  BearChild  阅读(159)  评论(0编辑  收藏  举报