题意
给定一个h*w的地图,然后输入n个坐标,表示在这些位置上放置有灯泡;又输入m个坐标,表示在这些位置上放置石头。灯泡可以沿上下左右四个方向发射光线,光线会被石头挡住。现在问在这个地图上被照亮的方块有多少个。
思路
既然有四个方向,那么就分别从四个方向对地图进行标记。比如考虑光线朝左的情况,首先肯定要遍历整个地图,在每行刚开始的时候我们可以定一个flag,表示距离当前判定位置最近的石头的位置,如果找到新的石头,那么就更新flag的值;如果遇到灯泡,假设此时位置是j,那么就对flag+1~j这几个位置进行标记,全标记完把flag改为j,这样可以加快标记的速度,其他三个方向上的判断方法同理。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1505;
int mymap[N][N],is[N][N],ans;
int main(){
int n,m,h,w,x,y;
scanf("%d %d %d %d",&h,&w,&n,&m);
for (int i=1;i<=n;i++){
scanf("%d %d",&x,&y);
mymap[x][y]=1;
}
for (int i=1;i<=m;i++){
scanf("%d %d",&x,&y);
mymap[x][y]=2;
}
//光线朝左
for (int i=1;i<=h;i++){
for (int j=1,flag=0;j<=w;j++){
if (mymap[i][j]==2) flag=j;
if (mymap[i][j]==1){
for (int k=flag+1;k<=j;k++) is[i][k]=1;
flag=j;
}
}
}
//光线朝右
for (int i=1;i<=h;i++){
for (int j=w,flag=w+1;j>=1;j--){
if (mymap[i][j]==2) flag=j;
if (mymap[i][j]==1){
for (int k=flag-1;k>=j;k--) is[i][k]=1;
flag=j;
}
}
}
//光线向下
for (int i=1;i<=w;i++){
for (int j=h,flag=h+1;j>=1;j--){
if (mymap[j][i]==2) flag=j;
if (mymap[j][i]==1){
for (int k=flag-1;k>=j;k--) is[k][i]=1;
flag=j;
}
}
}
//光线向上
for (int i=1;i<=w;i++){
for (int j=1,flag=0;j<=h;j++){
if (mymap[j][i]==2) flag=j;
if (mymap[j][i]==1){
for (int k=flag+1;k<=j;k++) is[k][i]=1;
flag=j;
}
}
}
//光线向下
for (int i=1;i<=h;i++){
for (int j=1;j<=w;j++){
if (is[i][j]) ans++;
}
}
printf("%d",ans);
return 0;
}