Description
平面上有N个点,任意2个点确定一条直线,求出所有这些直线中,斜率最大的那条直线所通过的两个点。
(点的编号为1-N,如果有多条直线斜率相等,则输出所有结果,按照点的X轴坐标排序,正序输出。数据中所有点的X轴坐标均不相等)
Input
第1行,一个数N,N为点的数量。(2 <= N <= 10000) 第2 - N + 1行:具体N个点的坐标,X Y均为整数(-10^9 <= X,Y <= 10^9)
Output
每行2个数,中间用空格分隔。分别是起点编号和终点编号(起点的X轴坐标 < 终点的X轴坐标)
Input示例
5
1 2
6 8
4 4
5 4
2 3
Output示例
4 2
证明最优解一定是在相邻两个点之间。
然后顺便感慨一下,隔壁O(n2)的暴力居然过了……目瞪口呆。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 struct node{int x,y,num;}a[10010]; 7 int n,cnt,t=2,ans[10010]; 8 double lv=-2e9; 9 bool cmp(node a,node b){return a.x<b.x;} 10 int comp(double i,double j) 11 { 12 if(fabs(i-j)<1e-6)return 0; 13 if(i>j)return 1; 14 return -1; 15 } 16 double xl(int i,int j){return (double)(a[j].y-a[i].y)/(a[j].x-a[i].x);} 17 int main() 18 { 19 scanf("%d",&n); 20 for(int i=1;i<=n;i++) 21 { 22 scanf("%d%d",&a[i].x,&a[i].y); 23 a[i].num=i; 24 } 25 sort(a+1,a+n+1,cmp); 26 while(t<=n) 27 { 28 double f=xl(t-1,t); 29 if(comp(f,lv)>0){lv=f;cnt=0;ans[++cnt]=t-1;ans[++cnt]=t;} 30 else if(comp(f,lv)==0)ans[++cnt]=t; 31 t++; 32 while(t<=n&&comp(xl(t-2,t-1),xl(t-1,t))>0)t++; 33 } 34 for(int i=1;i<=cnt;i++)printf("%d ",a[ans[i]].num); 35 return 0; 36 }
时间: 2024-10-08 18:51:49