CCF认证考试题解目录
题目背景
某地疫情爆发后,出于“应检尽检”的原则,我们想要通知所有近期经过该高危区域的居民参与核酸检测。
问题描述
想要找出经过高危区域的居民,分析位置记录是一种简单有效的方法。
具体来说,一位居民的位置记录包含 t 个平面坐标 (x1,y1),(x2,y2),⋯,(xt,yt),其中 (xi,yi) 表示该居民 i 时刻所在位置。
高危区域则可以抽象为一个矩形区域(含边界),左下角和右上角的坐标分别为 (xl,yd) 和 (xr,yu),满足 xl<xr 且 yd<yu。
考虑某位居民的位置记录,如果其中某个坐标位于矩形内(含边界),则说明该居民经过高危区域;进一步地,如果其中连续 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说明
如下图红色标记所示,前三条位置记录经过了高危区域;
但第三条位置记录(图中左上曲线)只有一个时刻位于高危区域内,不满足逗留条件。
样例输入2
样例输出2
样例2说明
该位置记录经过了高危区域,但最多只有连续两个时刻位于其中,不满足逗留条件。
评测用例规模与约定
全部的测试点满足 1≤n≤20,1≤k≤t≤103,所有坐标均为整数且绝对值不超过 106。
C++题解
记录经过高危区的人数很简单,在内层循环中只要有一次在该区域内就将人数加一;对于逗留高危区的人数,则要考虑到该人是否是连续的K次都驻留在高危区,我采用的方法需要考虑特殊情况:该人从进入高危区就没有出来过的这种情况,所以最后判断sum变量和K的大小关系,决定是否将逗留人数加1.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N,K,T,Xl,Yd,Xr,Yu,jingguo=0,douliu=0;
scanf("%d%d%d%d%d%d%d",&N,&K,&T,&Xl,&Yd,&Xr,&Yu);
while(N--)
{
int sum = 0, max = 0,t = T;
while(t--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>=Xl&&y>=Yd&&x<=Xr&&y<=Yu) sum++;
else
{
if(sum>max)
{
max = sum;
}
sum=0;
}
}
if(max>0||sum>0) jingguo++;
if(max>=K||sum>=K) douliu++;
}
printf("%d\n%d",jingguo,douliu);
return 0;
}