其他分享
首页 > 其他分享> > JZOJ 3833. 平坦的折线

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%的数据如题目。

 

分析

 

 

代码

 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 }

 

标签:lam,JZOJ,int,3833,45,mid,折线,include
来源: https://www.cnblogs.com/zjzjzj/p/11805732.html