1. 程式人生 > >【51nod 1100】斜率最大

【51nod 1100】斜率最大

alt mil -1 closed 個數 斜率 return hid %d

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 }
View Code

【51nod 1100】斜率最大