cf1301f

cf1301f

1. sujeto al efecto

Le dará una \ (n * m \) de matriz, cada pequeña rejilla tiene un color, el color está representado por un número entero, no más de \ (K \) . Cada vez que se puede subir y bajar la rejilla adyacente o saltar directamente a uno del mismo color y la parrilla hasta su ubicación actual. Ahora hay \ (q \) preguntas, cada pregunta para usted de \ (r1, c1 \) fueron \ (r2, c2 \) ¿Cuánto tiempo es el mínimo requerido.

2. Rango de datos

\ (1 \ leq n, m \ leq 1000,1 \ leq k \ leq 40,1 \ leq q \ leq 10 ^ 5 \) .

3. Solución

Avance en esta cuestión es que \ (K \) rango es relativamente pequeña. Sabemos que sólo hay dos posibilidades para la generación de respuestas a cada pregunta, ya sea directamente llegamos a la final desde el principio, entonces la respuesta es la distancia Manhattan entre dos puntos, o transmitida a través de varios colores diferentes.

El primer caso es el cálculo muy simple y directa.

La segunda situación más complicada, podemos suponer que después de un cierto color desde el principio hasta el centro del extremo (i \) \ transporte, siempre y cuando nos encontramos desde el principio hasta el color \ (i \) es la distancia más corta \ (x \ ) y desde el punto final al color \ (i \) es la distancia más corta \ (el y- \) , entonces el tiempo nuestra respuesta es \ (la dirección X + Y- el 1 + \) . Buscando el origen al color \ (I \) es la distancia más corta, podemos usar \ (BFS \) para hacer, tal complejidad tiempo de pretratamiento es \ (O (n-K * m *) \) . Por supuesto, se puede sospechar que un particular, no es necesario añadir 1, la idea es de hecho correcta, pero si no es esto una ventaja, pero añadimos una, así que esto no va a ser nuestra respuesta correcta. Como suponemos que se trata de pasar por lo menos una vez con la transferencia de color, a continuación enumeramos todo \ (i \) , que debe ser capaz de enumerar la misma transferencia de color.

La complejidad tiempo total: \ (O (m * K * + K * n-Q) \)

4. Código

#include<bits/stdc++.h>
using namespace std;  
int const N=1000+10;  
int const K=40+2;  
short d[N][N][K]; 
int n,m,k,vis[K],a[N][N],cnt,h[K],Q;  
int dx[4]={0,0,1,-1}; 
int dy[4]={1,-1,0,0};  
queue<int> q;  
struct edge{
    int t1,t2,nt;  
}e[N*N];  
void add(int a,int x,int y){
    e[++cnt].t1=x;e[cnt].t2=y; e[cnt].nt=h[a]; h[a]=cnt;  
}
void bfs(int c){
    int l=0,r=-1;  
    for(int i=h[c];i;i=e[i].nt){
        int x=e[i].t1;  
        int y=e[i].t2;  
        d[x][y][c]=0;  
        q.push(x); 
        q.push(y);   
    }
    memset(vis,0,sizeof(vis));  
    while (!q.empty()){
        int x=q.front(); q.pop(); 
        int y=q.front(); q.pop(); 
        if(!vis[a[x][y]]){
            vis[a[x][y]]=1; 
            for(int i=h[a[x][y]];i;i=e[i].nt){
                int tx=e[i].t1;  
                int ty=e[i].t2; 
                if(d[tx][ty][c]==-1){
                    d[tx][ty][c]=d[x][y][c]+1;  
                    q.push(tx); 
                    q.push(ty); 
                }
            }
        }
        for(int i=0;i<4;i++){
            int tx=x+dx[i];  
            int ty=y+dy[i];  
            if(tx<1 || ty<1 || tx>n || ty>m) continue;  
            if(d[tx][ty][c]>-1) continue;  
            q.push(tx); 
            q.push(ty); 
            d[tx][ty][c]=d[x][y][c]+1;  
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&k);  
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) {
            scanf("%d",&a[i][j]);  
            add(a[i][j],i,j);  
        }
    memset(d,-1,sizeof(d));  
    for(int i=1;i<=k;i++)  
        bfs(i);  
    scanf("%d",&Q);  
    while (Q--){
        int x1,y1,x2,y2;  
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 
        int ans=abs(x1-x2)+abs(y1-y2);  
        for(int i=1;i<=k;i++)  
            ans=min(ans,d[x1][y1][i]+d[x2][y2][i]+1);  
        printf("%d\n",ans);  
    }
    return 0; 
}

Supongo que te gusta

Origin www.cnblogs.com/ZJXXCN/p/12571922.html
Recomendado
Clasificación