开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第28天,点击查看活动详情
【ICPC】2020南京站 L. Let's Play Curling | 排序、set
题目链接
题目
题目大意
红队和蓝队玩冰球。
游戏结束后,数轴上有 个红色冰球分别位于数轴上的 点,有 个蓝色冰球分别位于数轴上的 点。如果球门位于 点,那么红队得到的积分是满足以下要求的红球的数量:
- 该球与球门的距离小于所有蓝球到球门的距离。
即满足红队的得分是满足条件 且 的 的数量。
现在我们不知道球门的具体位置,试求红队可能取得的最高分是多少。如果红队可能取得的最高分是 ,就输出 Impossible
。
多组数据。
思路
我们把红球和蓝球都标注在数轴上。容易只需将球门放在发现连续的一段红球覆盖的区间的中点上,这连续的一段红球就都可以对答案产生贡献。
容易发现一段红球中如果有蓝球,那么他们不可能同时对答案产生贡献。
首先如果一个红球和一个蓝球重合,那么该位置的红球一定不会对答案产生贡献。为了便于统计连续红球的数量,我们直接把和蓝球在同一个坐标的红球删去。用 STL 里的容器 set 可以轻松实现该功能。
然后把所有球放在一起排序,坐标从小到大遍历所有球,遇见蓝球计数器清空,遇见红球计数器加一即可。每次修改计数器的值后更新答案。
代码
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <math.h>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
using LL=long long;
const int N=1e6+5;
const LL mod=1e9+7;
struct asdf{
int val,typ;
}x[N];
int n,m,k,a[N];
set<int> v;
bool cmp(asdf a,asdf b)
{
return a.val<b.val;
}
LL solve()
{
v.clear();
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%d",&a[i]);
for (int i=1;i<=m;++i)
{
scanf("%d",&x[i].val);
x[i].typ=2;
v.insert(x[i].val);
}
for (int i=1;i<=n;++i)
{
if (v.count(a[i])) continue;
x[++m]={a[i],1};
}
sort(x+1,x+1+m,cmp);
int ans=0,cnt=0;
for (int i=1;i<=m;++i)
{
if (x[i].typ==1) cnt++;
else cnt=0;
ans=max(ans,cnt);
}
if (ans==0) printf("Impossible\n");
else printf("%d\n",ans);
return 0;
}
int main()
{
int T=1;
scanf("%d",&T);
while (T--) solve();
return 0;
}