GYM 100090 A. After Two Hares(水~)

本文介绍了一种基于矩阵的地图游戏中,通过放置炸弹来捕获两只野兔的问题解决方法。使用前缀和数组来快速判断是否能同时炸晕两只野兔,并提供了一个C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
给出一张n*m的图,“#”表示强,“.”表示空,现在可以往任一空点扔一个炸弹,炸弹的冲击波会往上下左右移动,遇到墙会被挡住,遇到野兔就会把它炸晕,现在往两个点放两只野兔,问是否可以通过合理放置炸弹炸晕这两只兔子
Input
第一行两整数n和m分别表示地图行列数,之后一个n*m矩阵表示该张地图,之后一整数q表示查询数,每次查询输入两只兔子的坐标x1,y1,x2,y2(1<=n,m<=2500,1<=q<=800000,1<=x1,x2<=n,1<=y1,y2<=m)
Output
对于每次查询,如果可以炸晕这两只兔子则输出YES,否则输出NO
Sample Input
这里写图片描述
Sample Output
YES
YES
YES
YES
NO
NO
NO
Solution
只有这两个点所处的长方形的另外两个顶点可能是答案,分别判断一下即可,判断标准就是该点到这两个点的边上没有#,预处理一个前缀和数组即可
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 2555
char s[maxn][maxn];
int x[maxn][maxn],y[maxn][maxn];
int n,m,q;
int main()
{
    while(~scanf("%d%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)   
                x[i][j]=y[i][j]=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                x[i][j]=x[i][j-1];
                if(s[i][j]=='#')x[i][j]++;
            }
        for(int j=1;j<=m;j++)
            for(int i=1;i<=n;i++)
            {
                y[i][j]=y[i-1][j];
                if(s[i][j]=='#')y[i][j]++;
            }
        scanf("%d",&q);
        while(q--)
        {
            int x1,y1,x2,y2,ans;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(x1>x2)swap(x1,x2),swap(y1,y2);
            if(y1<=y2)
            {
                int num1=y[x2][y1]-y[x1-1][y1]+x[x2][y2]-x[x2][y1-1];
                int num2=y[x2][y2]-y[x1-1][y2]+x[x1][y2]-x[x1][y1-1];
                if(num1&&num2)ans=0;
                else ans=1;
            }
            else
            {
                int num1=y[x2][y1]-y[x1-1][y1]+x[x2][y1]-x[x2][y2-1];
                int num2=y[x2][y2]-y[x1-1][y2]+x[x1][y1]-x[x1][y2-1];
                if(num1&&num2)ans=0;
                else ans=1;
            }
            printf("%s\n",ans?"YES":"NO");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值