P1332 血色先锋队
题目描述
军团是一个 n 行 m 列的矩阵,每个单元是一个血色先锋军的成员。感染瘟疫的人,每过一个小时,就会向四周扩散瘟疫,直到所有人全部感染上瘟疫。你已经掌握了感染源的位置,任务是算出血色先锋军的领主们感染瘟疫的时间,并且将它报告给巫妖王,以便对血色先锋军进行一轮有针对性的围剿。
输入格式
第 11 行:四个整数 n,m,a,b,表示军团矩阵有 n 行 m 列。有 a 个感染源,b 为血色敢死队中领主的数量。
接下来 a 行:每行有两个整数 x,y,表示感染源在第 x 行第 y 列。
接下来 b 行:每行有两个整数 x,y,表示领主的位置在第 x 行第 y 列。
输出格式
第 1 至 b 行:每行一个整数,表示这个领主感染瘟疫的时间,输出顺序与输入顺序一致。如果某个人的位置在感染源,那么他感染瘟疫的时间为 0。
输入输出样例
输入
5 4 2 3
1 1
5 4
3 3
5 3
2 4
输出
3
1
3
说明/提示
输入输出样例 1 解释
如下图,标记出了所有人感染瘟疫的时间以及感染源和领主的位置。
数据规模与约定
对于 100% 的数据,保证 1≤n,m≤500,1≤a,b≤10^5 。
思路
这个是典型的bfs,将每一个感染源入队列,然后生成整个地图,最后根据输入的坐标输出。
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b;
int pos[5005][5005];//记录每个位置被感染的时间
struct node{
int x,y;
};
queue<node> q;
int dx[]={1,0,0,-1};
int dy[]={0,1,-1,0};
int main(){
cin>>n>>m>>a>>b;
memset(pos,-1,sizeof pos); //将每个点都标记为-1,表示都未走过
for(int i=1;i<=a;i++){
int x,y;cin>>x>>y;//输入感染源
q.push({x,y});//感染源入队列
pos[x][y]=0;//将感染源标记为0
}
while(!q.empty()){
int xx=q.front().x;
int yy=q.front().y;
q.pop();
for(int k=0;k<4;k++){
int tx=xx+dx[k],ty=yy+dy[k];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m){
if(pos[tx][ty]==-1){//如果这个点未走过
pos[tx][ty]=pos[xx][yy]+1;
q.push({tx,ty});
}
}
}
}
for(int i=0;i<b;i++){
int x,y;
cin>>x>>y;//输入要查的坐标
cout<<pos[x][y]<<endl;
}
return 0;
}