JZOJ 3833. 平坦的折线

题目

Description

       现在我们在一张纸上有一个笛卡尔坐标系。我们考虑在这张纸上用铅笔从左到右画的折线。我们要求任何两个点之间连接的直线段与x轴的夹角在-45~45之间,一条满足以上条件的折线称之为平坦的折线。假定给出了n个不同的整点(坐标为整数的点),最少用几条平坦的折线可以覆盖所有的点?


例子:

图中有6个整点:(1,6), (10,8), (1,5), (2,20), (4,4), (6,2),要覆盖它们至少要3条平坦的折线。

 
任务:
写一个程序:
从文件lam.in中读入点的个数以及它们的坐标。
计算最少需要的折线个数。
将结果写入文件lam.out。
 

Input

       在输入文件lam.in的第一行有一个正整数n,不超过30000,代表点的个数。接下来的n行表示这些点的坐标,每行有两个用一个空格隔开的整数x,y,0 <= x <= 30000, 0 <= y <= 30000。第i+1行的数字代表第i个点的坐标。

Output

       在输出文件lam.out的第一行应当有且仅有一个整数——表示覆盖所有的点最少需要的折线数。
 

Sample Input

6
1 6
10 8
1 5
2 20
4 4
6 2
 

Sample Output

3
 

Data Constraint

数据规模
对于20%的数据,有N<=15。
对于100%的数据如题目。

 

分析

 

  • 首先我们需要对坐标做如下操作
  • 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 }

 

posted @ 2019-11-06 15:48  Melted_czj  阅读(114)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色