大致意思就是給出n對座標點,每對組成乙個線段。如果兩個線段有重合的部分則兩條線段可以合併為一條(或者兩條線段端點相連,斜率相同也可以合併),求最後剩下幾條。
乙個n表示n條線段,然後又n行,每行四個浮點數,兩個數為乙個座標,兩個座標表示一條線段。
輸出剩下的線段條數
先對輸入進行排序,沒有斜率的時候,y值小的儲存在前;有斜率(包括斜率為0),x值小的儲存在前。
然後從第一條和後邊的n-1條進行比較,有重合的就進行合併,然後再比第二條,以此直到最後兩條線段的比較。
資料結構:用了乙個線段類,其實是複雜了。
/*
在一堆線段中找出重合的那些,並合併。
輸出最後剩下幾條線段。
放到sicily上超時。應該還能改進。
*/
#include#include#include
const
double errors = 0.000001
;//判斷兩個浮點數是否相等
bool isequal(double a, double
b)
else
}//線段類,主要用來判斷兩條線段是否重合,組合重合的線段
class
linesegment
; linesegment(
double, double, double, double
); ~linesegment() {};
void
combine(linesegment);
bool
iscoincide(linesegment);
private
:
double x[2
];
double y[2
];
double
slope;//線段的斜率
double
x0;//與y軸的交點
bool
o_slope;
};//含參建構函式
linesegment::linesegment(
double x1, double x2, double y1, double
y2)
else
x0 =x1;
}else
else
//計算斜率和與y軸的交點slope = (y2 - y1) / (x2 -x1);
x0 = y1 - x1 *slope;
}}//判斷兩條線段是否重合
bool
linesegment::iscoincide(linesegment t)
else
else}}
else
else
else}}
}void
linesegment::combine(linesegment t)
if (y[0] > t.y[0
]) }
else
if (x[0] > t.x[0
]) }
}int
main()
int result = n;for (int i = 0; i < n; i++) }}
cout
<< result
>n; }}
線段樹合併
做永無鄉的時候,以為是主席樹合併,後來感覺不對勁,唔。x和y是兩顆樹的根。這個演算法是從歸併演算法那引申的。實際運作的時候,考慮到了線段樹的本質 線段樹有效節點就是葉子節點。好像是句廢話。其實不是,這句話啟發我們並不需要合併一整棵樹,我們只需要處理好葉子節點,考慮把y樹合併到x上,那麼把y樹的葉子節...
線段樹合併
今天寫dsu on tree 的時候發現不會寫線段樹合併,於是滾來寫線段樹合併部落格 對於值域相同的兩個權值線段樹x xx和y yy 假設把y yy合併到x xx上 每個節點有兩種情況 其中至少有乙個節點沒有權值 x y x y x y 直接x x y x x y x x y x 0?y x x 0...
線段樹合併
某一天馬學長給我看了乙個lca的題目,然而確實是lca 樹上差分,但是僅僅有lca和樹上差分解決不了,然後我就去面向題解程式設計了。可是這個線段樹合併是個什麼東東。然而今天看書,突然看到了這個線段樹合併。就寫一下了。mmh。p4556 vani有約會 雨天的尾巴 題目背景 深繪里一直很討厭雨天。灼熱...