1. 程式人生 > >2018/11/02 膜你賽 波浪

2018/11/02 膜你賽 波浪

題目:

題目描述
在第一象限裡,有一個海灘上時不時有波浪。
一個波浪用一個數字對(x,y)表 示,代表一個頂點為(00),(x,0),(0,y),(x,y)的矩形。
每一個波浪會沖刷掉其範圍內的其他波浪留下的痕跡,並保持自己的痕跡(x,0)

(x,ÿ)和(0,y) - >(x,y)。 
現在海岸上的人想知道 n 波後海岸上的痕跡總長度。
輸入資料保證一個波浪不會 完全覆蓋另一個波浪。

輸入輸出格式
輸入格式:
第一行是波浪的數量 n(n <= 50000)。 
下面為 n 行,每行包含兩個數字(x,y),( 0 < x,y ≤ 10000000)表示每一 個波浪。

輸出格式:
單行輸出答案。

輸入輸出樣例
輸入樣例#1
3 1 4 4 1 3 3 輸出樣例#110 說明 30%的資料滿足:n<=1000 < x,y ≤ 1000100%的資料滿足:n <= 500000 < x,y ≤ 10000000

題目:
倒著考慮,這裡把後到的浪稱作先到的浪,先到的浪稱作後到的浪。
然後對於每個浪,分別考慮x,y座標,只需要知道對於比它的座標小一點的浪它多戳出來的一截的長度就好了。
可以用set處理。
有一個函式set.lower_bound(x),可以找到第一個插入set中不破壞原序列單調性的位置。

程式碼:

#include<bits/stdc++.h>
using namespace std;

#define
maxn 50000
#define ll long long #define read(x) scanf("%d",&x) int n; int X[maxn+5],Y[maxn+5]; ll ans; set<int> st1,st2; int main() { read(n); for(int i=n;i>=1;i--) read(X[i]),read(Y[i]); st1.insert(0),st2.insert(0); for(int i=1;i<=n;i++) { set<int>::iterator it=st1.lower_bound
(X[i]); it--; ans+=(X[i]-*it); st1.insert(X[i]); } for(int i=1;i<=n;i++) { set<int>::iterator it=st2.lower_bound(Y[i]); it--; ans+=Y[i]-*it; st2.insert(Y[i]); } printf("%lld",ans); return 0; }