Pregunta diaria de la Copa Blue Bridge 20223.9.26

4407. Buscaminas - Banco de preguntas de AcWing

Descripción de la pregunta

analizar

Esta pregunta expirará cuando usemos el mapa, etc., por lo que podemos usar inteligentemente hash para simular una tabla hash. La tabla hash se inicializa a -1. Primero, lea la mina en la tabla hash y encuentre el subíndice correspondiente de la mina. coordenadas en la tabla hash. De lo contrario, la ubicación de esta mina aparece por primera vez y se almacena en la tabla hash. di[key] representa el subíndice de la mina correspondiente a la clave en la matriz hash. Tome el radio más grande entre estos minas en la misma posición, porque el máximo El radio de explosión es mayor

Enumere los misiles, si hay una mina, no ha sido visitada y está dentro del alcance de la explosión, puede destruirla.

Finalmente, recorra cada mina para ver si está marcada, si está marcada, es la respuesta.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int X = 1e9 + 1, M = 1e6 + 7, N = 5e4 + 10;
struct node
{
	int x, y, r;
}b[N];
ll h[M], id[M], res, n, m;
bool st[N];
ll get_he(int x, int y)//得到每个坐标的哈希值 
{
	return (ll)x * X + y;
}
int find(int x, int y)//找到坐标被哈希数组储存的下标 
{
	ll he = get_he(x, y);
	int key = (he % M + M) % M;//映射哈希数组内 
	while(h[key] != -1 && h[key] != he)
	{
		key ++;
		if(key == M)key = 0;
	}
	return key;
}
bool check(int x, int y,int r, int xx, int yy)//判断是否在爆炸范围内 
{
	int d = (x - xx) * (x - xx) + (y - yy) * (y - yy);
	return d <= r * r;
}
void bfs(int pos)
{
	queue<int>q;
	q.push(pos);
	st[pos] = true;
	while(!q.empty())
	{
		int t = q.front();
		q.pop();
		int x = b[t].x, y = b[t].y, r= b[t].r;
		for(int xx = x - r; xx <= x + r; xx ++)
		{
			for(int yy = y - r; yy <= y + r; yy ++)
			{
				int key = find(xx, yy);
				//是地雷,没有访问过,能炸到 
				if(id[key] && !st[id[key]] && check(x, y, r, xx, yy))
				{
					int pos = id[key];
					st[pos] = true;
					q.push(pos);
				}
			}
		}
	}
}
int main()
{
	cin >> n >> m;
	memset(h, -1, sizeof h);
	int x, y, r;
	for(int i = 1; i <= n; i ++)//地雷 
	{
		cin >> x >> y >> r;
		b[i] = {x, y, r};
		int key = find(x, y);//找到此地雷对应的下标 
		if(h[key] == -1)h[key] = get_he(x, y);//如果此下标没有出现过就加入 
		if(!id[key] || b[id[key]].r < r)
		{
			id[key] = i;
		}
	}
	for(int i = 1; i <= m; i ++)//排雷导弹
	{
		cin >> x >> y >> r;
		for(int xx = x - r; xx <= x + r; xx ++)//在r的范围内,但可以以圆外的方形区域作为边界 
		{
			for(int yy = y - r; yy <= y + r; yy ++)
			{
				int key = find(xx, yy);
				if(id[key] && !st[id[key]] && check(x, y, r, xx, yy))bfs(id[key]);
			}
		}	
	} 
	for(int i = 1; i <= n; i ++)
	{
		int key = find(b[i].x, b[i].y);
		int pos = id[key];
		if(pos && st[pos])res ++;
	}
	cout << res;
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/m0_75087931/article/details/133325324
Recomendado
Clasificación