Queso ~ Estrategia de poda para búsqueda en profundidad primero

Descripción del Título

Hay un gran trozo de queso, su altura es hh, su largo y ancho pueden considerarse infinitos, hay muchas cavidades esféricas con el mismo radio en el medio del queso. Podemos establecer un sistema de coordenadas espaciales en esta pieza de queso En el sistema de coordenadas, la superficie inferior del queso es z = 0 y la superficie superior del queso es z = h.

Ahora, hay un pequeño ratón Jerry en la superficie inferior del queso, conoce las coordenadas de los centros de todos los agujeros en el queso. Si dos cavidades son tangentes o se cruzan, Jerry puede correr de una cavidad a la otra. En particular, si una cavidad es tangente o se cruza con la superficie inferior, Jerry puede entrar en la cavidad desde la superficie inferior del queso; si una cavidad es tangente o se cruza con la superficie superior, y Jerry puede correr desde la cavidad hasta la superficie superior del queso.

Jerry, que se encuentra en la superficie inferior del queso, quiere saber si puede usar las cavidades existentes para correr hacia la superficie superior del queso sin destruir el queso.
Inserte la descripción de la imagen aquí

Formato de entrada

Inserte la descripción de la imagen aquí

Formato de salida

Inserte la descripción de la imagen aquí

Muestra de entrada

3 
2 4 1 
0 0 1 
0 0 3 
2 5 1 
0 0 1 
0 0 4 
2 5 2 
0 0 2 
2 0 4

Salida de muestra

Yes
No
Yes

Instrucciones / consejos

Inserte la descripción de la imagen aquí

Tamaño de datos

Inserte la descripción de la imagen aquí

Código AC

#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1005;
ll n,h,r;
struct xy{
    
    
	ll x,y,z;
}a[maxn];
inline bool cmp(const xy &z1,const xy &z2){
    
    
	return z1.z < z2.z;
}
inline bool isOk(const xy &z1,const xy &z2){
    
    
	if(sqrt((z1.x-z2.x)*(z1.x-z2.x)+(z1.y-z2.y)*(z1.y-z2.y)+(z1.z-z2.z)*(z1.z-z2.z)) <= 2*r){
    
    
		return true;
	}
	return false;
}
bool isAlright = false;
void solve(xy x,ll s,ll g){
    
    
	if(g + r >= h){
    
    
		isAlright = true;
	}
	for(ll i=s;i<=n;i++){
    
    
		if(a[i].z - x.z > 2*r || isAlright)	break;
		else{
    
    
			if(isOk(x,a[i])){
    
    
				solve(a[i],i+1,a[i].z);
			}
		}
	}
}
int main()
{
    
    
	int T;
	cin>>T;
	while(T --){
    
    
		isAlright = false;
		cin>>n>>h>>r;
		for(ll i=1;i<=n;i++){
    
    
			cin>>a[i].x>>a[i].y>>a[i].z;
		}
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++){
    
    
			if(a[i].z - r <= 0 && !isAlright){
    
    
				solve(a[i],i+1,a[i].z);
			}
		}
		if(!isAlright){
    
    
			cout<<"No";
		}
		else{
    
    
			cout<<"Yes";
		}
		cout<<endl;
	}
	return 0;
}

Envíe a todos dos conjuntos de datos de prueba

6
2 1000 250
0 0 250
0 0 751
2 1000 400
400 750 5
840 716 718
3 2000 600
328 1454 1005
114 736 1503
860 131 556
4 5000 1000
1249 4828 4646
4638 2770 880
289 267 2924
142 2875 3957
5 1060 300
634 586 1008
756 332 385
570 40 776
428 176 380
695 1028 36
6 8765 4321
2468 2920 3602
613 6875 33
1935 230 809
4916 7853 4995
5960 1560 2989
1758 4793 6410

No
No
No
No
No
Yes
5
1 100 60
70 27 88
1 100 75
80 39 34
1 100 50
605 563 50
1 200 160
120 176 40
1 200 10
50 47 84

No
Yes
Yes
Yes
No

Explicación

① Esta pregunta usa búsqueda combinada, tanto la búsqueda amplia como la búsqueda profunda pueden resolverse. Yo uso la búsqueda profunda aquí.
②Entender la pregunta es muy importante. La pregunta establece claramente que Jerry comienza desde (0,0,0), lo que significa que si no hay un campo de pelota que pueda incluir el punto (0,0,0), Jerry no puede caminar., Solo salida directamente No.
③ Búsqueda profunda:

bool isAlright = false;
void solve(xy x,ll s,ll g){
    
    
	if(g + r >= h){
    
    
		isAlright = true;
	}
	for(ll i=s;i<=n;i++){
    
    
		if(a[i].z - x.z > 2*r || isAlright)	break;
		else{
    
    
			if(isOk(x,a[i])){
    
    
				solve(a[i],i+1,a[i].z);
			}
		}
	}
}

Para ser honesto, la idea de esta búsqueda profunda no es única. No es difícil pensar que usé una variable s en lugar de la matriz vis booleana, y omití el paso de juzgar si este punto ha sido, porque después de la entrada ya hemos alineado la bola de acuerdo con la altura de la esfera. El centro está ordenado, por lo que cada vez que se alcanza un centro de esfera, en la matriz que almacena las coordenadas del centro de la esfera, el valor z (altura) de la siguiente coordenada del centro de la esfera debe ser más alto (o igual) que el centro actual de la esfera. Si busca un camino profundo y no puede llegar al punto final, puede encontrar otro camino desde otra carretera a la misma altura ).
Poda: la poda es una característica importante de esta pregunta, y el código se usa dos veces para podar; de lo contrario, todas las pruebas posteriores señalarán TLE.
La poda se utiliza por primera vez, antes de ingresar a la función de resolución:

for(int i=1;i<=n;i++){
    
    
	if(a[i].z - r <= 0 && !isAlright){
    
    //这一步用到了剪枝
		solve(a[i],i+1,a[i].z);
	}
}

Este paso: if(a[i].z - r <= 0 && !isAlright)es decir, si la esfera donde se encuentra el centro de la esfera no incluye el origen, omítalo, y si ha encontrado una salida, finaliza el juicio.
La poda se utiliza por segunda vez, en la función de resolución:

for(ll i=s;i<=n;i++){
    
    
	if(a[i].z - x.z > 2*r || isAlright)	break;//这一步用到了剪枝
		else{
    
    
			if(isOk(x,a[i])){
    
    
				solve(a[i],i+1,a[i].z);
			}
		}
	}

Es decir: if(a[i].z - x.z > 2*r || isAlright) break;si el centro actual de la esfera no puede alcanzar la siguiente esfera, el bucle finaliza, o si se ha encontrado una salida, el bucle finaliza.
⑤AC.

Supongo que te gusta

Origin blog.csdn.net/fatfairyyy/article/details/113850322
Recomendado
Clasificación