Cod sursa(job #1458039)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 6 iulie 2015 10:53:47
Problema Kdrum Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>

#define NMAX 57

struct kdrum{
    int x, y, Conf, Nr;
};

const int Dx[] = {0, 0,  0, 1, -1};
const int Dy[] = {0, 1, -1, 0,  0};

using namespace std;

vector < int > Div;
queue < kdrum > q;
int n, m, k;
int a[NMAX][NMAX], Viz[NMAX][NMAX][NMAX];
int FinalConf;
int XS, YS, XF, YF;

int make_new_config(int CONF, int Number){
    for(int i = 0; i < Div.size(); ++i)
        if(!(CONF & (1 << i)) && Number % Div[i] == 0){
            CONF |= (1 << i);
            Number /= Div[i];
        }
    return CONF;
}

kdrum make_kdrum(int X, int Y, int CONF, int NR){
    kdrum d;
    d.x = X;
    d.y = Y;
    d.Conf = CONF;
    d.Nr = NR;
    return d;
}

int main(){
    freopen("kdrum.in", "r", stdin);
    freopen("kdrum.out", "w", stdout);
    scanf("%d %d %d", &n, &m, &k);
    scanf("%d %d %d %d", &XS, &YS, &XF, &YF);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%d", &a[i][j]);
    while(k % 2 == 0){
        Div.push_back(2);
        k /= 2;
        FinalConf += (1 << (Div.size() - 1));
    }
    int Lim = sqrt(k);
    for(int i = 3; i <= Lim; i += 2)
        while(k % i == 0){
            Div.push_back(i);
            k /= i;
            FinalConf += (1 << (Div.size() - 1));
        }
    if(k > 0){
        Div.push_back(k);
        FinalConf += (1 << (Div.size() - 1));
    }
    kdrum Final = make_kdrum(XF, YF, FinalConf, 1);
    int NewConf = make_new_config(0, a[XS][YS]);
    q.push(make_kdrum(XS, YS, NewConf, 1));
    Viz[XS][YS][NewConf] = 1;
    int Nr = 0;
    while(! q.empty() && Final.Nr == 1){
        kdrum Nod = q.front();
        q.pop();
        for(int i = 1; i <= 4 && Final.Nr == 1; ++i){
            kdrum NewNod = make_kdrum(Nod.x + Dx[i], Nod.y + Dy[i], make_new_config(Nod.Conf, a[Nod.x + Dx[i]][Nod.y + Dy[i]]), Nod.Nr + 1);
            if(Viz[NewNod.x][NewNod.y][NewNod.Conf] == 1 || a[NewNod.x][NewNod.y] == 0)
                continue;
            if(NewNod.x == Final.x && NewNod.y == Final.y && NewNod.Conf == Final.Conf)
                Final = NewNod;
            q.push(NewNod);
            Viz[NewNod.x][NewNod.y][NewNod.Conf] = 1;
        }
    }
    printf("%d", Final.Nr);
    return 0;
}