这题一看非常蒙 因为要求太宽了
一开始可以秒掉就是用一条水平/竖直折线连接所有点 所有的拐点输出就行
总共已知的点数是1e4 也就是说总点数要加成nlgn
想到分治 二分中线然后所有点往中线投影 一共分lgn次 满足题意
注意去重 开个set重载==就可以
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<iostream> 7 #define ms(a,b) memset(a,b,sizeof a) 8 #define rep(i,a,n) for(int i = a;i <= n;i++) 9 #define per(i,n,a) for(int i = n;i >= a;i--) 10 #define inf 1e18 11 using namespace std; 12 typedef long long ll; 13 typedef double D; 14 #define eps 1e-8 15 ll read() { 16 ll as = 0,fu = 1; 17 char c = getchar(); 18 while(c < '0' || c > '9') { 19 if(c == '-') fu = -1; 20 c = getchar(); 21 } 22 while(c >= '0' && c <= '9') { 23 as = as * 10 + c - '0'; 24 c = getchar(); 25 } 26 return as * fu; 27 } 28 const int N = 200005; 29 //head 30 int n; 31 struct node { 32 int x,y; 33 bool operator < (const node &o) const { 34 return x == o.x ? y < o.y : x < o.x; 35 } 36 bool operator == (const node &o) const { 37 return x == o.x && y == o.y; 38 } 39 }p[N],ans[N<<2]; 40 int top = 0; 41 //[l,r) 42 void solve(int l,int r) { 43 if(l >= r) return; 44 int m = l+r >> 1; 45 rep(i,l,r) ans[++top] = (node){p[m].x,p[i].y}; 46 solve(l,m),solve(m+1,r); 47 } 48 49 int main() { 50 n = read(); 51 rep(i,1,n) { 52 p[i].x = read(),p[i].y = read(); 53 ans[++top] = p[i]; 54 } 55 sort(p+1,p+n+1),solve(1,n); 56 sort(ans+1,ans+1+top); 57 top = unique(ans+1,ans+1+top) - (ans+1); 58 printf("%d ",top); 59 rep(i,1,top) printf("%d %d ",ans[i].x,ans[i].y); 60 return 0; 61 }