JZOJ 3833. 平坦的折线
题目
分析
- 首先我们需要对坐标做如下操作
- x'=x-y y'=x+y
- 使点旋转45度
- 然后我们就知道当线段延长交角的度数0<x<90为合法
- 我们考虑排序让一些单调递增的点连起来
- 但是这要做许多遍lis
- 所以我们反过来想
- 我们求一次单调低减 因为递减的点必须要作为线的开端
- 所以Lis即可
代码
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define ll long long 7 using namespace std; 8 struct sb 9 { 10 int x,y; 11 }a[30001]; 12 bool cmp(sb a,sb b) 13 { 14 if (a.x!=b.x) return a.x<b.x?true:false; 15 else return a.y<b.y?true:false; 16 } 17 int f[30001]; 18 int main() 19 { 20 freopen("lam.in","r",stdin); 21 freopen("lam.out","w",stdout); 22 int n; 23 cin>>n; 24 for (int i=1,x,y;i<=n;i++) 25 { 26 cin>>x>>y; 27 a[i].x=x-y; 28 a[i].y=x+y; 29 } 30 sort(a+1,a+1+n,cmp); 31 f[1]=a[1].y; 32 int len=1; 33 for (int i=2;i<=n;i++) 34 { 35 if (a[i].y<f[len]) 36 f[++len]=a[i].y; 37 else 38 { 39 int l=1,r=len; 40 while (l<=r) 41 { 42 int mid=l+r>>1; 43 if (f[mid]>a[i].y) l=mid+1; 44 else r=mid-1; 45 } 46 f[l]=a[i].y; 47 } 48 } 49 cout<<len; 50 return 0; 51 }
为何要逼自己长大,去闯不该闯的荒唐