1. 问题链接:CCF 202009-2 风险人群筛查
试题编号: | 202009-2 |
试题名称: | 风险人群筛查 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 题目背景某地疫情爆发后,出于“应检尽检”的原则,我们想要通知所有近期经过该高危区域的居民参与核酸检测。 问题描述想要找出经过高危区域的居民,分析位置记录是一种简单有效的方法。 具体来说,一位居民的位置记录包含 t 个平面坐标 (x1,y1),(x2,y2),⋯,(xt,yt),其中 (xi,yi) 表示该居民 i 时刻所在位置。 考虑某位居民的位置记录,如果其中某个坐标位于矩形内(含边界),则说明该居民经过高危区域;进一步地,如果其中连续 k 个或更多坐标均位于矩形内(含边界),则认为该居民曾在高危区域逗留。需要注意的是,判定经过和逗留时我们只关心位置记录中的 t 个坐标,而无需考虑该居民在 i 到 i+1 时刻之间位于何处。 给定高危区域的范围和 n 位居民过去 t 个时刻的位置记录,试统计其中经过高危区域的人数和曾在高危区域逗留的人数。 输入格式输入共 n+1 行。 第一行包含用空格分隔的七个整数 n、k、t、xl、yd、xr 和 yu,含义如上文所述。 接下来 n 行,每行包含用空格分隔的 2t 个整数,按顺序表示一位居民过去 t 个时刻的位置记录 (x1,y1),(x2,y2),⋯,(xt,yt)。 输出格式输出共两行,每行一个整数,分别表示经过高危区域的人数和曾在高危区域逗留的人数。 样例输入1样例输出1样例1说明如下图红色标记所示,前三条位置记录经过了高危区域;
扫描二维码关注公众号,回复:
14988612 查看本文章
样例输入2样例输出2样例2说明该位置记录经过了高危区域,但最多只有连续两个时刻位于其中,不满足逗留条件。 评测用例规模与约定全部的测试点满足 1≤n≤20,1≤k≤t≤103,所有坐标均为整数且绝对值不超过 106。 |
2. 问题分析:
经过读题分析,本题难点在于判断 连 续 \color{red}\large{\bold{连续}} 连续k 个或更多坐标均位于矩形内(含边界),也就是是否存在高危区域逗留。我此处采用的是通过输入流处理直接统计连续经过高危区域的坐标数量,然后对最大值进行迭代,最后判断一位居民是否存在逗留情况。需要注意prev初始化为t时刻保证第一次不会进行统计,以后始终赋值为最新经过高危区域的坐标时刻,cnt变量表示当前连续经过高危区域的坐标数量。
3. C++语言程序实现:
#include <bits/stdc++.h>
using namespace std;
bool in_danger_area(int &xl,int &yd,int &xr,int &yu,int x,int y)
{
if (x>=xl&&x<=xr&&y>=yd&&y<=yu)
{
return true;
}
else
{
return false;
}
}
int main()
{
int n,k,t,xl,yd,xr,yu,xt,yt,passed=0,leaved=0,cnt,prev,adjacent_max;
scanf("%d%d%d%d%d%d%d",&n,&k,&t,&xl,&yd,&xr,&yu);
for (int i=0; i<n ; ++i )
{
bool is_in=false;
prev=t;
cnt=1,adjacent_max=0;
for (int j=0; j<t ; ++j )
{
scanf("%d%d",&xt,&yt);
if (in_danger_area(xl,yd,xr,yu,xt,yt))
{
if (j-prev==1)
{
adjacent_max=max(++cnt,adjacent_max);
}
else
{
cnt=1;
}
prev=j;
is_in=true;
}
}
if (is_in)
{
++passed;
}
if (adjacent_max>=k)
{
++leaved;
}
}
printf("%d\n%d",passed,leaved);
return 0;
}