Cod sursa(job #2185605)

Utilizator CristyXtremeSimion Cristian CristyXtreme Data 24 martie 2018 18:07:28
Problema Kdrum Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <cstdio>
#include <queue>

using namespace std;

FILE *g=fopen("kdrum.out","w");
int n,m,k,map[52][52],poz[12001],dl[4]={-1,0,1,0},dc[4]={0,1,0,-1},xv,yv,drumv,xi,yi,xf,yf;
struct triplu{int x,y,rest;};
queue <triplu> Q;
vector <int> divizor, dp[52][52];

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

inline triplu make_triplu(int a,int b,int c)
{
    triplu tr;
    tr.x=a;
    tr.y=b;
    tr.rest=c;
    return tr;
}

void citire()
{
    FILE *f=fopen("kdrum.in","r");
    fscanf(f,"%i %i %i",&n,&m,&k);
    fscanf(f,"%i %i %i %i",&xi,&yi,&xf,&yf);
    for(int i=1;i<=k;i++)
        if(k%i==0)
        {
            poz[i]=divizor.size();
            divizor.push_back(i);
        }
    for(int i=1,a;i<n+1;i++)
        for(int j=1;j<m+1;j++)
        {
            fscanf(f,"%i",&a);
            if(a)
                map[i][j]=cmmdc(a,k);
            dp[i][j].resize(divizor.size());
        }
}

void bordare()
{
    for(int i=0;i<n+2;i++)
    {
        map[i][0]=-1;
        map[i][m+1]=-1;
    }
    for(int i=0;i<m+2;i++)
    {
        map[0][i]=-1;
        map[n+1][i]=-1;
    }
}

void lee()
{
    triplu curent,viitor;
    Q.push(make_triplu(xi,yi,poz[map[xi][yi]]));
    dp[xi][yi][poz[map[xi][yi]]]=1;
    while(!Q.empty())
    {
        curent=Q.front();
        for(int i=0;i<4;i++)
        {
            xv=curent.x+dl[i];
            yv=curent.y+dc[i];
            drumv=poz[cmmdc(k,divizor[curent.rest]*map[curent.x][curent.y])];
            if((map[xv][yv]>0)&&((dp[xv][yv][drumv]==0)||(dp[xv][yv][drumv]>dp[curent.x][curent.y][curent.rest]+1)))
            {
                dp[xv][yv][drumv]=dp[curent.x][curent.y][curent.rest]+1;
                Q.push(make_triplu(xv,yv,drumv));
            }
        }
        Q.pop();
    }
}

int main()
{
    citire();
    bordare();
    lee();
    fprintf(g,"%i\n",dp[xf][yf][divizor.size()-1]);
    return 0;
}