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;
}