Cod sursa(job #1990527)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 12 iunie 2017 13:30:28
Problema Kdrum Scor 50
Compilator cpp Status done
Runda Simulare 14b Marime 2.63 kb
#include <cstdio>
#include <queue>

using namespace std;

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

const int nmax = 50;
const int kmax = 12000;
const int vmax = 1e5;
const int factmax = 5;
const int logmax = 13;

const int dl[ 4 ] = {-1, 0, 0, 1};
const int dc[ 4 ] = {0, 1, -1, 0};

vector< pair<int, int> > p;
int pt[factmax + 1][logmax + 1];
int e[vmax + 1][factmax + 1];

int n, m, k;
int v[nmax + 1][nmax + 1];
int d[nmax + 1][nmax + 1][kmax + 1];

struct str {
    int x, y, nr;

    str() {}
    str (int _x, int _y, int _nr) {
        x = _x, y = _y, nr = _nr;
    }
};

queue< str > q;

void precalc() {
    int aux = k;
    for (int i = 2; i * i <= aux; ++ i) {
        if (aux % i == 0) {
            int eXp = 0;
            pt[ (int)p.size() ][ 0 ] = 1;

            while (aux % i == 0) {
                ++ eXp;
                pt[ (int)p.size() ][ eXp ] = pt[ (int)p.size() ][eXp - 1] * i;

                aux /= i;
            }

            p.push_back(make_pair(i, eXp));
        }
    }

    if (aux != 1) {
        pt[ (int)p.size() ][ 0 ] = 1;
        pt[ (int)p.size() ][ 1 ] = aux;
        p.push_back(make_pair(aux, 1));
    }

    for (int i = 1; i <= vmax; ++ i) {
        for (int j = 0; j < (int)p.size(); ++ j) {
            int cnt = 0;
            aux = i;
            while (aux % p[ j ].first == 0) {
                ++ cnt;
                aux /= p[ j ].first;
            }
            e[ i ][ j ] = cnt;
        }
    }
}

int combina (int x, int y) {
    int ans = 1;
    for (int i = 0; i < (int)p.size(); ++ i) {
        ans *= pt[ i ][min(e[ x ][ i ] + e[ y ][ i ], p[ i ].second)];
    }
    return ans;
}

int main() {
    int stx, sty, fnx, fny;
    fscanf(fin, "%d%d%d", &n, &m, &k);
    fscanf(fin, "%d%d%d%d", &stx, &sty, &fnx, &fny);

    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) {
            fscanf(fin, "%d", &v[ i ][ j ]);
        }
    }

    precalc();

    int shp = combina(1, v[ stx ][ sty ]);
    d[ stx ][ sty ][ shp ] = 1;

    q.push(str(stx, sty, shp));

    while (!q.empty() && d[ fnx ][ fny ][ k ] == 0) {
        str w = q.front(); q.pop();

        for (int dir = 0; dir < 4; ++ dir) {
            int x = w.x + dl[ dir ], y = w.y + dc[ dir ];

            if (x < 1 || n < x || y < 1 || m < y) continue;
            if (v[ x ][ y ] == 0) continue;

            shp = combina(w.nr, v[ x ][ y ]);
            if (d[ x ][ y ][ shp ] != 0) continue;

            d[ x ][ y ][ shp ] = d[ w.x ][ w.y ][ w.nr ] + 1;
            q.push(str(x, y, shp));
        }
    }

    fprintf(fout, "%d\n", d[ fnx ][ fny ][ k ]);

    fclose( fin );
    fclose( fout );
    return 0;
}