经典题! 双指针枚举半平面,求最大最小值
2017-05-31 21:44
351 查看
4880: [Lydsy2017年5月月赛]排名的战争
Time Limit: 8 Sec Memory Limit:256 MB
Submit: 281 Solved: 53
[Submit][Status][Discuss]
Description
小Q是一名出色的质检员,他负责质检一批手机的质量。手机包含两个性能属性:电池寿命x_1与坚硬度x_2。小Q将为它们评估综合质量分数,具体地说,他将选择两个非负实数w_1,w_2,且$_1,w_2不能同时为0,则一部手机的综
合分数s=w_1*x_1+w_2*x_2。在评定出所有手机的分数后,小Q会把手机按分数从高到低排序,若有多部手机分数相
同,他可以将它们随意排列,因此每部手机的排名都是独一无二的。聪明的你会发现,对于不同的w的选定,手机
的最终排名可能会大不一样。因此各个公司都会暗中贿赂小Q,希望他让自己的排名尽量靠前。现一共有n家公司,
每家公司提供了一部手机用于质检。tangjz知道小Q可以通过调参来控制排名,所以他想知道他的公司的手机排名
最高是多少,最低是多少。
Input
第一行包含一个正整数n(1<=n<=100000),即公司的个数。接下来n行,每行两个正整数x_1,x_2(1<=x_1,x_2<=1000),分别表示每部手机的两个属性。
tangjz所在公司提供的手机总是输入里的第一部手机。
Output
输出一行两个整数,即最高排名与最低排名。Sample Input
57 7
11 10
8 5
1 1
12 12
Sample Output
3 4千万不能想当然直接排序暴力!!!!
#include<bits/stdc++.h> using namespace std; int n,x,y,X,Y,summ,cnt,m; struct node { int x,y,z;double o; node(){} node(int xx,int yy,int zz) { x=xx;y=yy;z=zz;o=atan2(y,x); } }a[200010],b[400010];int sum[400010]; bool cmp(node p1,node p2){return p1.o<p2.o;} int check(node p1,node p2){return p1.x*p2.y-p2.x*p1.y;} int main() { scanf("%d",&n);n--;scanf("%d%d",&X,&Y); while(n--) { scanf("%d%d",&x,&y); if(x==X&&y==Y){summ++;continue;} a[++cnt]=node(x-X,y-Y,1);a[++cnt]=node(X-x,Y-y,0); } if(cnt==0){printf("1 %d\n",summ+1); return 0;} sort(a+1,a+cnt+1,cmp); for(int i=1,j=1;i<=cnt;i=j) { int summm=0; for(j=i;j<=cnt&&a[i].o==a[j].o;j++)summm+=a[j].z; b[++m]=node(a[i].x,a[i].y,summm); } for(int i=1;i<=m;i++)b[m+i]=b[i]; for(int i=1;i<=m+m;i++)sum[i]=sum[i-1]+b[i].z; int ansmin=1e7,ansmax=0; int sum1=0,sum2=0; for(int i=1,j=1;i<=m;i++) { if(b[i].x<0||b[i].y>0)continue;//必须保证斜率比第一个大(第一个(X,Y)) if(j<i)j=i; while(j+1<i+m&&check(b[i],b[j+1])>=0)j++;//找到第一个斜率比i小的。 sum1=sum[j]-sum[i-1];sum2=b[i].z; if(i<j&&check(b[i],b[j])==0)sum2+=b[j].z;//如果第i个和第j个斜率还相同,说明名次还能在上升b[j].z名和降低b[j].z名 sum1-=sum2;sum2+=summ; ansmax=max(ansmax,sum[j]-sum[i-1]+summ+1);//ansmax=max(ansmax,sum1+sum2+summ+1); ansmin=min(ansmin,sum1+1); } printf("%d %d\n",ansmin,ansmax);return 0; }
相关文章推荐
- algrothm_经典[]求最大值最小值
- Spark经典案例5-求最大最小值
- 第四届河南省acm省赛 走迷宫(二分法枚举差值和最大值最小值+DFS)
- Java算法求最大最小值,冒泡排序,斐波纳契数列一些经典算法<不断更新中>
- Java算法求最大最小值,冒泡排序,斐波纳契数列,日历一些经典算法
- POJ 3189--Steady Cow Assignment【二分图多重匹配 && 最大流求解 && 枚举 && 经典】
- POJ 2455--Secret Milking Machine【二分枚举 && 最大流 && 经典】
- 用指针求最大最小值
- (枚举)算法竞赛入门经典(7.1.2)最大乘积
- (枚举)算法竞赛入门经典(7.1.2)最大乘积
- Java算法求最大最小值,倒序,冒泡排序,斐波纳契数列,日历一些经典算法
- 分治法的经典问题——求数列中最大最小值
- 二叉查找树带父节点指针的创建,销毁,查找,删除,插入,找前驱后继,找最小值最大值(递归和非递归的实现)
- java-第五章-while-输入一些整数,输入0结束循环,算出最大值最小值
- poj--3264Balanced Lineup+ST算法求区间最大最小值
- C经典 函数指针的三种使用方式
- 经典算法(3)——最大间隙问题(线性时间算法)
- int、long、float、double最大最小值
- 关于二维矩阵的最大最小值的询问
- 【C语言】求二维数组最大值最小值平均值