题意
给你一个nxm的网格,刚开始每个坐标(i,j)都有一个盒子,现在你做执行q次操作,每次将(x,y)坐标上的盒子消失,这样会影响到求他盒子,当一个盒子的上下中的一个盒子消失了并且左右的一个一个盒子消失了这个盒子也会消失,大网格看作一个最大的盒子,当在边缘的盒子如果一个盒子的左边是边缘,那么我将左边的墙壁当作一个不可以消失的盒子。
思路
简单bfs,对于一个消失的盒子标记,我们在入队之前应该打上标记而不是在出队列的时候打标机。
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int n,m,q;
int map[2222][2222];
struct node{
int x,y;
};
int mx[4]={1,0,-1,0};
int my[4]={0,1,0,-1};
int bfs(int x,int y)
{
if(map[x][y]) return 0;
queue<node> qu;
qu.push({x,y});
int ans=0;
map[x][y]=1;
while(!qu.empty())
{
node t=qu.front();qu.pop();
ans+=1;
//map[xx][yy]=1;不可以在这里,因为这样会导致在队列中的还没访问到的盒子打不了标记
for(int i=0;i<4;i++)
{
int xx=t.x+mx[i];
int yy=t.y+my[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!map[xx][yy])
{
if((map[xx+1][yy]||map[xx-1][yy])&&(map[xx][yy+1]||map[xx][yy-1]))
{
map[xx][yy]=1;
qu.push({xx,yy});
}
}
}
}
return ans;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&q);
memset(map,0,sizeof(map));
for(int i=0;i<q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",bfs(x,y));
}
}
return 0;
}