题目描述
题目大意:一个正方形的网格,你与木乃伊轮流移动(你走出第一步)。轮到你时,你可以移动到相邻的8个格子之一,或者站着不动。轮到木乃伊时,每个木乃伊会移动到其相邻的格子之一,使得他与你的欧几里得距离尽量小(假设你与木乃伊都站在格子的中心位置)。允许多个木乃伊同时占据同一个格子。
在每个单位时间内,你先做出移动,然后木乃伊做出移动。如果你与任何一个木乃伊站在同一位置,你会被抓住。当然,你试图尽量长时间避免被抓住。经过多少单位时间你会被抓住呢?
题解
首先二分答案,然后将H和每一个木乃伊能在这个时间内能到达的点标记出来,可以发现是n+1个正方形。没有被抓住的条件是H所确定的正方形不是所有木乃伊所确定的正方形的并的子集。
用扫描线求解。首先将纵坐标离散,然后将木乃伊的正方形分解成左右两个线段,然后按照横坐标排序。每一次遇到一条线段在范围内加减,然后每一次判断是否被完全覆盖了即可,注意顺序应该为加、统计答案、减。
但是有一些特殊的边界条件需要判断:如果存在某一列根本就没有操作不能跳过去,也应该判断;H的左边界和右边界要判断;如果有某一行为空的话在离散化的时候应该往里加进去一行(试了很久不加点的方法都不科学qwq
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 100005
int T,n,Max,Min,LSH,cnt,ans;
struct P{
int x,y;}p[N];
struct LINE{
int x,l,r,val;}line[N<<1];
int lsh[400004],cover[1000005],sum[1000005];
void clear()
{
Max=Min=LSH=cnt=ans=0;
memset(lsh,0,sizeof(lsh));
}
int cmp(LINE a,LINE b)
{
return a.x<b.x||(a.x==b.x&&a.val>b.val);
}
void update(int now,int l,int r)
{
if (cover[now]) sum[now]=r-l+1;
else if (l==r) sum[now]=