Cod sursa(job #1920238)

Utilizator akaprosAna Kapros akapros Data 9 martie 2017 23:05:46
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <bits/stdc++.h>
#define maxN 52
#define maxM 52
#define maxK 12002
#define maxD 202
#define inf 1000000000
using namespace std;

FILE *fin = freopen("kdrum.in", "r", stdin);
FILE *fout = freopen("kdrum.out", "w", stdout);

/* -------------------- */
int n, m, k, a[maxN][maxN];
struct Cell
{
    int x, y, d;
} b, e;
/* -------------------- */
int dp[maxN][maxN][maxD], Div[maxD], idx[maxK];
queue < Cell > q;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
/* -------------------- */

int gcd(int x, int y)
{
    int r = x % y;
    while (r)
    {
        x = y;
        y = r;
        r = x % y;
    }
    return y;
}

void read()
{
    scanf("%d %d %d", &n, &m, &k);
    scanf("%d%d%d%d", &b.x, &b.y, &e.x, &e.y);
    for (int i = 1; i <= n; ++ i)
        for (int j = 1; j <= m; ++ j)
        {
            scanf("%d", &a[i][j]);
            a[i][j] = gcd(a[i][j], k);
        }
}

bool ok(int x, int y)
{
    return (x > 0 && y > 0 && x <= n && y <= m && a[x][y]);
}

void init()
{
    for (int i = 1; i <= n; ++ i)
        for (int j = 1; j <= m; ++ j)
            for (int d = 1; d <= Div[0]; ++ d)
                dp[i][j][d] = inf;
}

void get_div()
{
    Div[++ Div[0]] = 1;
    Div[++ Div[0]] = k;
    for (int i = 2; i * i <= k; ++ i)
        if (k % i == 0)
        {
            Div[++ Div[0]] = i;
            if (i * i != k)
                Div[++ Div[0]] = k / i;
        }
    sort(Div + 1, Div + Div[0] + 1);
    for (int i = 1; i <= Div[0]; ++ i)
        idx[Div[i]] = i;
}

void solve()
{
    int d = gcd(k, a[b.x][b.y]);
    get_div();

    init();
    dp[b.x][b.y][idx[d]] = 1;
    q.push({b.x, b.y, idx[d]});
    while (!q.empty())
    {
        Cell nod = q.front();
        q.pop();
        for (int d = 0; d < 4; ++ d)
            if (ok(nod.x + dx[d], nod.y + dy[d]))
            {
                int g = idx[gcd(a[nod.x + dx[d]][nod.y + dy[d]] * Div[nod.d], k)];
                if (dp[nod.x + dx[d]][nod.y + dy[d]][g] > dp[nod.x][nod.y][nod.d] + 1)
                {
                    dp[nod.x + dx[d]][nod.y + dy[d]][g] = dp[nod.x][nod.y][nod.d] + 1;
                    q.push({nod.x + dx[d], nod.y + dy[d], g});
                }
            }
    }
}

void write()
{
    printf("%d\n", dp[e.x][e.y][idx[k]]);
}

int main()
{
    read();
    solve();
    write();
    return 0;
}