JZOJ5685. 【GDOI2018Day1模拟4.24】恐怖袭击

24 篇文章 0 订阅

Description

有情报称H市有恐怖分子要发动一场恐怖袭击。现在已知恐怖分子的坐标是(sx,sy),他将要发动袭击的位置是(tx,ty)。现在有n名特警,他们的位置分别是(x1,y1),(x2,y2),…,(xn,yn)。在每个单位时间内,恐怖分子和每个特警可以选择朝上下左右移动1的距离或者原地不动。因为特警完全掌握了恐怖分子的情报,每个特警可以根据恐怖分子在这个单位时间内的移动来决定自己这个单位时间内如何移动。如果在某个时刻恐怖分子和某个特警处在同一个坐标,那么恐怖分子就会被这个特警抓住。恐怖分子的目标是先到达坐标(tx,ty),之后再想办法永远不会被特警抓住。你的任务是计算要用前多少名特警才能让恐怖分子不能达成他的目的,即输出最小的i使得只要我们有前i个分别在(x1,y1),(x2,y2),..,(xi,yi)的特警,那么恐怖分子就无法在到达(tx,ty)之后还不会被特警抓住。如果n名特警都在的情况下,恐怖分子依然能达成他的目标,那么输出n+1。

Input

第一行四个整数:sx,sy,tx,ty (-10^8<=sx,sy,tx,ty<=10^8) 分别表示恐怖分子的初始位置和将要发动恐怖袭击的位置。第二行一个整数:n (1<=n<=100000)表示特警的总数。之后n行每行两个数:x,y (-10^8<=x,y<=10^8)表示特警所处的位置。

Output

一个整数i,如题目描述。

Sample Input

输入1:
0 0 1 2
2
10 0
1 2

输入2:
0 0 1 2
2
10 0
4 3

Sample Output

输出1:
2
输出2:
3
【样例解释】
第一个样例,只有第一个特警抓不住恐怖分子,第二个特警就在袭击目标处,所以前两个特警就能抓住恐怖分子。第二个样例,两个特警一起都无法抓住恐怖分子。

Data Constraint

20%的数据保证:如果恐怖分子能到达恐怖袭击目标,那他一定能逃脱,否则答案一定是n,而且这n个特警在恐怖分子到达袭击目标之前就能破坏恐怖分子的计划。
另外30%的数据保证:初始时恐怖分子就在袭击目标处。
100%数据保证:所有坐标范围的绝对值不超过10^8,n不超过100000

题解

恐怖分子的逃跑最优路线一定就是朝着某个方向逃跑,
不可能是折线。
分两种情况,
1、某个特警在T这个位置将其逮捕,只需要这个警察能在恐怖分子到达T之前到达T就可以了,
2、4个逃跑方向都被封锁了,某个特警再去逮捕他。
就从前往后枚举特警,如果这个特警满足情况1,就可以成功逮捕,
否则就看看他可以把守哪些方向,1个特警不一定只能把守一个方向。
如果4个方向都被封锁了,且有空余的特警(恐怖分子可以选择原地不动)去逮捕他,那么也可以成功逮捕。

code

#include<cstdio>
#include<iostream>
#include<algorithm>
#define G getchar
using namespace std;
char ch;
void read(int &n)
{
    int w;
    for(ch=G();(ch<'0' || ch>'9') && ch!='-';ch=G());
    if(ch=='-')w=-1,ch=G();else w=1;
    for(n=0;'0'<=ch && ch<='9';ch=G())n=(n<<1)+(n<<3)+ch-48;
    n=n*w;
}

const int N=100003;
int x[N],y[N],sx,sy,tx,ty,n,t,m,dx,dy,w;
bool bz[5];

int disx(int id){return x[id]>tx?x[id]-tx:tx-x[id];}
int disy(int id){return y[id]>ty?y[id]-ty:ty-y[id];}

int main()
{
    freopen("attack.in","r",stdin);
    freopen("attack.out","w",stdout);
    read(sx);read(sy);read(tx);read(ty);
    read(n);t=abs(tx-sx)+abs(ty-sy);
    for(int i=1;i<=n;i++)
        read(x[i]),read(y[i]);
    for(int i=1;i<=n;i++)
    {
        dx=disx(i);dy=disy(i);
        if(dx+dy<=t)
        {
            printf("%d",i);
            return 0;
        }

        if(dy<=dx+t)
        {
            w=x[i]>tx?0:2;
            if(bz[w])m++;else bz[w]=1;
        }
        if(dx<=dy+t)
        {
            w=y[i]>ty?3:1;
            if(bz[w])m++;else bz[w]=1;
        } 

        if(m && bz[0] && bz[1] && bz[2] && bz[3])
        {
            printf("%d",i);
            return 0;
        }
    }
    printf("%d",n+1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值