bzoj1007 水平可見直線

2022-06-03 21:48:11 字數 1168 閱讀 2874

在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 00 0

1 2按照k排序,然後就可以維護乙個棧,從斜率小的直線往斜率大的直線掃,棧中都是目前可見直線。

每掃到乙個直線,就看棧頂直線是否已經被全部覆蓋(被當前直線擋住的右部分的左端點在它被擋住的最大左部分的右端點左邊),如果已經被全部覆蓋,就彈棧,一直到棧頂直線不會被覆蓋,這時的棧頂直線就會是擋住當前直線最大左部分的直線。

然後把當前直線放入棧中。最後棧中直線就是可見直線。

啊。。。我到底在說什麼。。。直接上**。

#include#include#include#include#include#includeusing namespace std;

const int maxn=50000+10;

int n,zz[maxn],e=0;

int aa,fl;char cc;

int read()

struct nodenode[maxn];

bool cmp(const node& x,const node& y)

int main()

sort(node+1,node+n+1,cmp);

for(int i=1;i<=n;++i) if(e==0||node[i].k!=node[zz[e]].k)

for(int i=1;i<=e;++i) zz[i]=node[zz[i]].pos;

sort(zz+1,zz+e+1);

for(int i=1;i<=e;++i) printf("%d ",zz[i]);

return 0;

}

BZOJ 1007 水平可見直線

題意 給出一些直線。從y軸正方向無窮遠處向下看能看到哪些?思路 如下圖,首先將直線按照斜率公升序排序,我們維護乙個單調的棧,棧頂top,設x i,j 表示i和j直線交點的橫座標,那麼x top,top 1 x i,top 時top可以被top 1和i完全覆蓋。比如下圖,首先我們將1和2壓入棧中。對於...

BZOJ1007水平可見直線 凸包

在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 且...

BZOJ1007 水平可見直線(單調棧)

在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 ...