Cod sursa(job #2272720)

Utilizator giotoPopescu Ioan gioto Data 30 octombrie 2018 16:49:11
Problema Kdrum Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, k;
int xA, xB, yA, yB;
int f[12005], rev[12005];
int d[55][55][105];
int a[55][55];
struct usu{
    int x, y, k;
};
queue <usu> q;
short dx[] = {-1, 1, 0, 0};
short dy[] = {0, 0, -1, 1};
inline int cmmdc(int x, int y){
    int r;
    while(y > 0){
        r = x % y;
        x = y; y = r;
    }
    return x;
}
inline void lee(){
    memset(d, 0x3f, sizeof(d));

    q.push({xA, yA, rev[cmmdc(k, a[xA][yA])]});
    d[xA][yA][rev[cmmdc(k, a[xA][yA])]] = 1;

    while(!q.empty()){
        int x = q.front().x, y = q.front().y, w = q.front().k;
        q.pop();
        for(short dir = 0; dir < 4 ; ++dir){
            int l = x + dx[dir];
            int c = y + dy[dir];
            if(!(l > 0 && c > 0 && l <= n && c <= m) || a[l][c] == 0) continue ;

            int val = cmmdc(a[l][c], k);
            val = val * rev[w];
            val = f[cmmdc(k, val)];

            if(d[l][c][val] > d[x][y][w] + 1){
                d[l][c][val] = d[x][y][w] + 1;
                if(l == xB && c == yB && val == 2) return ;
                q.push({l, c, val});
            }
        }
    }
}

int main(){
    freopen("kdrum.in", "r", stdin);
    freopen("kdrum.out", "w", stdout);

    scanf("%d%d%d", &n, &m, &k);
    scanf("%d%d%d%d", &xA, &yA, &xB, &yB);

    for(int i = 1; i <= n ; ++i)
        for(int j = 1; j <= m ; ++j)
            scanf("%d", &a[i][j]);

    int NR = 0;
    for(int i = 1; i * i <= k ; ++i){
        if(k % i == 0){
            f[i] = ++NR;
            rev[NR] = i;
            if(k / i != i){
                f[k / i] = ++NR;
                rev[NR] = k / i;
            }
        }
    }

    lee();
    printf("%d", d[xB][yB][2]);

    return 0;
}