Cod sursa(job #1304473)

Utilizator diana97Diana Ghinea diana97 Data 28 decembrie 2014 22:34:31
Problema Kdrum Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

ifstream f ("kdrum.in");
ofstream g ("kdrum.out");

const int NMAX = 50 + 1;
const int KMAX = 12000 + 1;

struct Nod {
    int x, y;
    int rest;
    Nod(int x, int y, int rest) {
        this->x = x;
        this->y = y;
        this->rest = rest;
    };
};

int n, m, k;
int x1, y1, x2, y2;
int dx[] = {-1,  0,  1,  0};
int dy[] = { 0,  1,  0, -1};
vector <int> divizori;
map <int, int> cost[NMAX][NMAX];
int index[KMAX];
int v[NMAX][NMAX];

inline int cmmdc(int a, int b) {
    if (!b) return a;
    return cmmdc(b, a % b);
}

inline void citeste() {
    f >> n >> m >> k;
    f >> x1 >> y1 >> x2 >> y2;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            f >> v[i][j];
            if (v[i][j]) v[i][j] = cmmdc(k, v[i][j]);
        }
}

inline void proceseaza() {
    int lim = k / 2;
    for (int i = 1; i <= lim; i++)
        if (k % i == 0) {
            divizori.push_back(i);
            index[i] = divizori.size() - 1;
        }
    divizori.push_back(k);
    index[k] = divizori.size() - 1;
}

inline bool inside(int x, int y) {
    //cout << x << ' ' << y << ' ' << n << ' ' << m << endl;
    if (x == 0 || x == n + 1) return false;
    if (y == 0 || y == m + 1) return false;
    return true;
}

void rezolva() {
    int x, y, rest, x_urm, y_urm, rest_urm;
    queue <Nod> Q;
    Q.push(Nod(x1, y1, index[v[x1][y1]]));
    cost[x1][y1][index[v[x1][y1]]] = 1;

    while(!Q.empty()) {
        x = Q.front().x;
        y = Q.front().y;
        rest = divizori[Q.front().rest];
        Q.pop();
        if (x == x2 && y == y2 && rest == k) {
            g << cost[x][y][index[rest]] << '\n';
            return;
        }
        for (int i = 0; i < 4; i++) {
            x_urm = x + dx[i];
            y_urm = y + dy[i];
            rest_urm = cmmdc(rest * v[x_urm][y_urm], k);
            if (inside(x_urm, y_urm) && v[x_urm][y_urm] != 0 && cost[x_urm][y_urm].count(index[rest_urm]) == 0) {
                Q.push(Nod(x_urm, y_urm, index[rest_urm]));
                cost[x_urm][y_urm][index[rest_urm]] = cost[x][y][index[rest]] + 1;
            }
        }
    }
}

int main() {
    int a, b;
    citeste();
    proceseaza();
    rezolva();
    return 0;
}