P2074 危险区域 AC于2018.8.7 https://www.luogu.org/problemnew/show/P2074

本文介绍了一个模拟炸弹威胁场景的算法问题,通过计算不同爆炸位置对城市街区的影响范围来确定最大受威胁区域。提供了两种实现方式,一种是递归搜索,另一种是循环遍历,帮助理解如何高效解决此类问题。

题目背景

一个恐怖组织在一座城市中安放了定时炸弹,其威力巨大,现在这里的警长想知道最坏的情况下会有多少街区受威胁。

题目描述

在一个城市有N*M个街区,每个街区由坐标描述,如图所示:

行 列 1 2 3 … M

1 (1,1) (1,2) (1,3) … (1,M)

2 (2,1) (2,2) (2,3) … (2,M)

3 (3,1) (3,2) (3,3) … (3,M)

… … … … … …

N (N,1) (N,2) (N,3) … (N,M)

现在已知有一个恐怖组织在其中的一个街区安放了定时炸弹,其威力为T,即所有到这个街区的直线距离小于等于T的街区都会受威胁,已知有K个可能的炸弹安放位置,现在这里的警长想知道最坏的情况下会有多少街区受威胁。

输入输出格式

输入格式:

第一行四个正整数N,M,K和T

接下来K行每行两个正整数Xi Yi,描述每个可能安放炸弹的街区。

输出格式:

一个正整数为在最坏情况下有多少街区会受威胁。

输入输出样例

输入样例#1: 

4 5 3 2
1 2
3 4
4 5

输出样例#1: 

11

说明

对于20%的数据 K=1

对于50%的数据 N,M≤1000 K≤20 T≤100

对于100%的数据 N,M≤100000 K≤50 T≤300

 

搜索版

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
int m,n,k,t,maxx,s,a,b;
double dis(int x,int y,int x1,int y1)
{
    return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
}
void dfs(int o)
{
    if(o>k)
    return ;
    scanf("%d%d",&a,&b);
    s=0;
    for(int i=max(1,a-t);i<=min(m,a+t);i++)
    for(int j=max(1,b-t);j<=min(n,b+t);j++)
    {
        if(dis(i,j,a,b)<=t)
        s++;//cout<<i<<j<<" ";
    }
    if(s>maxx)
    maxx=s;
    //cout<<s<<endl;
    dfs(o+1);
}
int main()
{
    scanf("%d%d%d%d",&m,&n,&k,&t);
    dfs(1);
    printf("%d",maxx);
    return 0;
}

循环版

#include<iostream>
#include<cstdio>
#include<cmath>
#define max(a,b) (a>b?a:b) 
#define min(a,b) (a>b?b:a)
using namespace std;
double dis(int x,int y,int a,int b)
{
    return sqrt((x-a)*(x-a)+(y-b)*(y-b));
}
int m,n,k,t,maxx,sum,c,d;
int main()
{
    scanf("%d%d%d%d",&n,&m,&k,&t);
    while(k--)
    {
        scanf("%d%d",&c,&d);
        sum=0;
        for(int i=max(1,c-t);i<=min(n,c+t);i++)
        for(int j=max(1,d-t);j<=min(m,d+t);j++)
        {
            if(dis(i,j,c,d)<=t)
            sum++;
        }
        if(sum>maxx)
        maxx=sum;
        cout<<sum<<endl;
    }
    printf("%d",maxx);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值