1. 程式人生 > >【BZOJ4880】排名的戰爭 [暴力]

【BZOJ4880】排名的戰爭 [暴力]

logs include discus 技術 所有 掃描 gre click 排列

排名的戰爭

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

【BZOJ4880】排名的戰爭 [暴力]