Cod sursa(job #2110088)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 20 ianuarie 2018 12:24:34
Problema Kdrum Scor 0
Compilator cpp Status done
Runda evaluare_cex_sv_cls_x_2 Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <queue>
std::ifstream f("kdrum.in");
std::ofstream g("kdrum.out");

int nr[55][55];
int N, M, K;
int y1, x1, y2, x2;
void citire() {
    f >> N >> M >> K;
    f >> y1 >> x1 >> y2 >> x2;
    for (int i=1, j; i<=N; i++)
        for (j=1; j<=M; j++)
            f >> nr[i][j];
}
int pasi_max = 15;

struct nod {
    int y, x, pasi=0, left=K;
};
int gcd(int a, int b) {     //dinamic?
    if(a==0) return b;
    if(b==0) return a;
    return gcd(b, a%b);
} void calcul(nod &nd, int x) {
    nd.left = nd.left/gcd(nd.left, x);
}

int lee2(int Y1, int X1, int Y2, int X2) {
    bool viz[180][180];
    for (int i=0, j; i<180; i++)
        for (j=0; j<180; j++)
            viz[i][j] = 0;
    for (int i=0; i<=N+1; i++)
        viz[0][i] = viz[i][0] = viz[N+1][i] = viz [i][N+1] = 1;
    struct nod {
    int y, x;
    int p=0;
    };
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    std::queue <nod> q;
    nod nd;
    nd.y = Y1;
    nd.x = X1;
    q.push(nd);
    nod nou, pres;

    while(!q.empty()) {
        pres = q.front();
        q.pop();

        if (pres.x == X2 && pres.y == Y2) {
            return pres.p;
        }

        for (int i=0; i<4; i++) {
            nou = pres; nou.p++;
            nou.x += dx[i]; nou.y += dy[i];
            if (!viz[nou.y][nou.x]) {
                q.push(nou);
                viz[nou.y][nou.x] = 1;
            }
        }
    }
}

void lee() {
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    std::queue <nod> q;
    nod pres, nou;
    nou.y = y1, nou.x = x1, nou.pasi = 0, nou.left = K;
    q.push(nou);

    while(!q.empty()) {
        pres = q.front();
        q.pop();
        if(pres.left == 1) {
            pasi_max = std::min(lee2(pres.y, pres.x, y2, x2)+pres.pasi, pasi_max);
        }

        else if(pres.y == y2 && pres.x == x2) {
            if(pres.left == 1)
                pasi_max = std::min(pasi_max, pres.pasi);
        } else

        for (int i=0; i<4; i++) {
            nou = pres;
            nou.y += dy[i]; nou.x += dx[i];
            nou.pasi ++;

            if(nr[nou.y][nou.x] && nou.pasi < pasi_max) {
                calcul(nou, nr[nou.y][nou.x]);
                q.push(nou);
            }
        }
    }
}


int main()
{
    citire();
    lee();
    g << pasi_max+1;

    return 0;
}