E. Two Platforms

题目链接

题意:

在一个平面上有n个点,放置两个长度为k的水平平台,n个点一直下降(y坐标减少),如果降到平台上,该点将会被保存,求怎样放置这两个平台,使保存的点最多。

思路:

由题可知,降在平台上的点与y坐标没关系,只要使用x坐标,将点按x坐标排序,求出以第i个点的x坐标为右端点长度为k的平台能保存的点的数量,数组l[i]记录从第1个点到第i个点之间长度为k的平台能保存的最多的点。

求出以第i个点的x坐标为左端点长度为k的平台能保存的点的数量,数组r[i]记录从第n个点往前到第i个点之间长度为k的平台能保存的最多的点数。

答案就是遍历n个点,找到l[i]+r[i+1]的最大值。

代码

 

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn=1e6+10;
 6 
 7 int x[maxn],l[maxn],r[maxn];
 8 void solve()
 9 {
10     int n,k;
11     scanf("%d %d",&n,&k);
12     for(int i=0; i<n; i++)
13         scanf("%d",&x[i]);
14     int y;
15     for(int i=0; i<n; i++)
16         scanf("%d",&y);
17     sort(x,x+n);
18     queue<int>q;
19     for(int i=0; i<n; i++)
20     {
21         if(!q.empty()&&q.front()<x[i]-k)
22             q.pop();
23         q.push(x[i]);
24         l[i]=q.size();
25         if(i>0)
26             l[i]=max(l[i],l[i-1]);
27     }
28     while(!q.empty())
29         q.pop();
30     for(int i=n-1; i>=0; i--)
31     {
32         if(!q.empty()&&q.front()-k>x[i])
33             q.pop();
34         q.push(x[i]);
35         r[i]=q.size();
36         if(i<n-1)
37             r[i]=max(r[i],r[i+1]);
38     }
39     int ans=0;
40     l[n]=r[n]=0;
41     for(int i=0; i<n; i++)
42         ans=max(ans,l[i]+r[i+1]);
43     printf("%d\n",ans);
44 }
45 signed main()
46 {
47     int _;
48     cin>>_;
49     while(_--)
50         solve();
51     return 0;
52 }

 

posted @ 2020-09-05 22:55  一个只会爆零的小菜鸡  阅读(283)  评论(0编辑  收藏  举报