程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 水平可見直線 bzoj 1007,可見直線bzoj1007

水平可見直線 bzoj 1007,可見直線bzoj1007

編輯:C++入門知識

水平可見直線 bzoj 1007,可見直線bzoj1007


水平可見直線 (1s 128M) lines

【問題描述】

在xoy直角坐標平面上有n條直線L1,L2,...Ln,若在y值為正無窮大處往下看,能見到Li的某個子線段,則稱Li為可見的,否則Li為被覆蓋的.

例如,對於直線:

L1:y=x; L2:y=-x; L3:y=0

則L1和L2是可見的,L3是被覆蓋的.

給出n條直線,表示成y=Ax+B的形式(|A|,|B|<=500000),且n條直線兩兩不重合.求出所有可見的直線.

【輸入格式】

第一行為N(0<N<50000),接下來的N行輸入Ai,Bi

【輸出格式】

從小到大輸出可見直線的編號,兩兩中間用空格隔開,最後一個數字後面也必須有個空格

【樣例輸入】

3

-1 0

1 0

0 0

【樣例輸出】

1 2


題解:

主要算法:計算幾何;快速排序;單調棧;

1.對於斜率相同的兩條直線截距小的被覆蓋。

2.對於斜率不同的三條直線,如果一條直線不可見

那麼必定是斜率最大和斜率最小的覆蓋另外一條線段

同時斜率最大和斜率最小的直線的交點在另一條線段的上方

根據這個性質,通過排序和單調棧即可維護可見直線。

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 inline int Get()
 9 {
10     int x = 0, s = 1;
11     char c = getchar();
12     while('0' > c || c > '9')
13     {
14         if(c == '-') s = -1;
15         c = getchar();
16     }
17     while('0' <= c && c <= '9')
18     {
19         x = (x << 3) + (x << 1) + c - '0';
20         c = getchar();
21     }
22     return x * s;
23 }
24 int n;
25 struct shape
26 {
27     int a, b, i;
28 };
29 shape a[100233];
30 int s[100233];
31 int ans[100233];
32 inline bool rule(shape a, shape b)
33 {
34     if(a.a != b.a) return a.a > b.a;
35     return a.b > b.b;
36 }
37 inline double Sol(int x, int y)
38 {
39     return (double) (a[y].b - a[x].b) / (double) (a[x].a - a[y].a);
40 }
41 int main()
42 {
43     n = Get();
44     for(int i = 1; i <= n; ++i)
45     {
46         a[i].a = Get();
47         a[i].b = Get();
48         a[i].i = i;
49     }
50     sort(a + 1, a + 1 + n, rule);
51     int top = 0;
52     for(int i = 1; i <= n; ++i)
53     {
54         if(a[i].a == a[s[top]].a) continue;
55         while(top > 1 && Sol(s[top], i) >= Sol(s[top], s[top - 1]))
56             --top;
57         s[++top] = i;
58         ans[top] = a[i].i;
59     }
60     sort(ans + 1, ans + 1 + top);
61     for(int i = 1; i <= top; ++i) printf("%d ", ans[i]);
62 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved