adding solution with constant heap time

This commit is contained in:
2026-05-08 15:18:32 -03:00
parent 63730e188b
commit a4fc2530e3

View File

@@ -0,0 +1,184 @@
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
#define MAX 150000
typedef struct node_t{
int i;
int j;
int c;
}node_t;
/*pantano*/
char mesh[1001][1001];
int custo[1002][1002];
char calculado[1002][1002];
int inserido[1002][1002];
node_t filas[8][MAX];
int contadoresInicio[8];
int contadoresFim[8];
int C,R;
int Cf,Rf,Ct,Rt;
int C1,R1,C2,R2;
int W;
int currentFila;
/*Escova bit*/
inline int get_int(){
int ch, i;
while (((ch = getchar()) == ' ') || (ch == '\n'));
for (i = 0; ch >= '0' && ch <= '9'; ch = getchar() )
i = 10 * i + (ch - '0');
return i;
}
void insere(node_t no,int custo){
int balde = custo%8;
inserido[no.i][no.j] = balde;
filas[balde][contadoresFim[balde]++] = no;
}
int retira(node_t* aux){
int start = currentFila;
while(contadoresInicio[currentFila]==contadoresFim[currentFila]){
currentFila++;
if(currentFila==8) currentFila = 0;
if(currentFila==start) return(0);
}
*aux = filas[currentFila][contadoresInicio[currentFila]++];
return(1);
}
/*Funcao q testa os limites do tabuleiro e outras coisas
*do Dijkstra
*/
int testa(node_t current,int i,int j,int c){
int custoAtual = custo[current.i][current.j];
node_t temp;
if(!(i<=R && i>=1 && j<=C && j>=1)){
return(1);
}
if(calculado[i][j]){
return(1);
}
if(mesh[i][j]==0){
/*relaxamento*/
if(custoAtual+c < custo[i][j]){
custo[i][j] = custoAtual+c;
/*insere normal*/
temp.i = i;
temp.j = j;
temp.c = custo[i][j];
insere(temp,(custo[i][j]));
}
return(1);
}
return(0);
}
int getFila(){
int i;
for(i=0;i<8;i++){
if(contadoresInicio[i]<contadoresFim[i]){
return(i);
}
}
return(8);
}
int main(void){
int i,j,k;
node_t aux;
node_t sapo;
while(C=get_int(),R=get_int(),C||R){
memset(mesh,0,sizeof(char)*1001*1001);
memset(custo,0x3f,sizeof(int)*1002*1002);
//~ memset(calculado,0,sizeof(char)*1002*1002);
//~ memset(inserido,-1,sizeof(int)*1002*1002);/*nenhum nó foi inserido ainda*/
memset(contadoresInicio,0,sizeof(contadoresInicio));
memset(contadoresFim,0,sizeof(contadoresFim));
Cf = get_int();
Rf = get_int();
Ct = get_int();
Rt = get_int();
W = get_int();
for(k=0;k<W;k++){
C1 = get_int();
R1 = get_int();
C2 = get_int();
R2 = get_int();
for(i=R1;i<=R2;i++){
for(j=C1;j<=C2;j++){
mesh[i][j] = 1;/*alagado*/
}
}
}
sapo.i = Rf; sapo.j = Cf;
custo[sapo.i][sapo.j] = 0;
insere(sapo,0);
currentFila = 0;
while(retira(&aux)){
if(aux.c > custo[aux.i][aux.j]) continue;
/*pega a frente de onda*/
//~ calculado[aux.i][aux.j] = 1;
/*Só faz sentido calcular o pulo mais distante
*de o pulo da frente tiver alagado
*/
/*Superior*/
if(!testa(aux,aux.i+1,aux.j,2))
testa(aux,aux.i+2,aux.j,5);
/*Diagonais*/
if(!testa(aux,aux.i+1,aux.j-1,3)){
testa(aux,aux.i+2,aux.j-2,7);
testa(aux,aux.i+2,aux.j-1,6);
testa(aux,aux.i+1,aux.j-2,6);
}
/*Diagonais*/
if(!testa(aux,aux.i+1,aux.j+1,3)){
testa(aux,aux.i+2,aux.j+2,7);
testa(aux,aux.i+2,aux.j+1,6);
testa(aux,aux.i+1,aux.j+2,6);
}
/*parte lateral*/
if(!testa(aux,aux.i,aux.j-1,2))
testa(aux,aux.i,aux.j-2,5);
if(!testa(aux,aux.i,aux.j+1,2))
testa(aux,aux.i,aux.j+2,5);
/*parte de baixo*/
if(!testa(aux,aux.i-1,aux.j,2))
testa(aux,aux.i-2,aux.j,5);
/*Diagonais*/
if(!testa(aux,aux.i-1,aux.j-1,3)){
testa(aux,aux.i-2,aux.j-2,7);
testa(aux,aux.i-1,aux.j-2,6);
testa(aux,aux.i-2,aux.j-1,6);
}
/*Diagonais*/
if(!testa(aux,aux.i-1,aux.j+1,3)){
testa(aux,aux.i-2,aux.j+2,7);
testa(aux,aux.i-2,aux.j+1,6);
testa(aux,aux.i-1,aux.j+2,6);
}
}
if(custo[Rt][Ct]==INF){
printf("impossible\n");
}
else{
printf("%d\n",custo[Rt][Ct]);
}
}
return(0);
}