题解 [ABC304C] Virus
大家好,我是 CQ-C2024 蒟蒻 CJH。
题意
有 $N$ 个人,他们分别在坐标为 $(X_i,Y_i)$ 的点上($N$ 个人的坐标互不相同)。
第一个人被感染了病毒,他将会传染给道他欧几里得距离小于等于 $D$ 的人。
请你求出 $N$ 个人是否被感染。
分析
传播病毒这种题,其实第一眼就会想到广度优先搜索。
于是只需要把 $1$ 加入队列,每次取出队首,在对 $n$ 个人进行遍历,如果队首到第 $i$ 个人欧几里得距离小于等于 $D$,就加入队列中即可。
时间复杂度 $O(n^2)$。
代码
//the code is from chenjh
#include<cstdio>
#include<queue>
int n,d;
bool dis(int x,int y,int X,int Y){//判断 (x,y) 到 (X,Y) 的欧几里得距离是否小于等于 D。
return (X-x)*(X-x)+(Y-y)*(Y-y)<=d*d;//直接拆开根号,就不需要进行开方运算了。
}
int xx[2002],yy[2002];
bool v[2002];//是否感染病毒。
int main(){
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++) scanf("%d%d",&xx[i],&yy[i]);
std::queue<int> Q;
Q.push(1);//第一个人感染病毒。
for(int u;!Q.empty();){
u=Q.front();Q.pop();
if(v[u]) continue;//感染过则不再进行下一波传染。
v[u]=1;//标记为感染。
for(int j=1;j<=n;j++)
if(j!=u && dis(xx[u],yy[u],xx[j],yy[j]) && !v[j])//注意:两个点不能是同一个点!
Q.push(j);
}
for(int i=1;i<=n;i++) puts(v[i]?"Yes":"No");
return 0;
}

浙公网安备 33010602011771号