【BZOJ4880】排名的戰爭 [暴力]
阿新 • • 發佈:2017-05-06
logs include discus 技術 所有 掃描 gre click 排列
[Submit][Status][Discuss]
手機包含兩個性能屬性:電池壽命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可以通過調參來控制排名,所以他想知道他的公司的手機排名最高是多少,最低是多少。
7 7
11 10
8 5
1 1
12 12
排名的戰爭
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
57 7
11 10
8 5
1 1
Sample Output
3 4HINT
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】排名的戰爭 [暴力]