Cod sursa(job #1594721)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 9 februarie 2016 18:23:23
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int Mn = 55;
const int Mk = 12005;
const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};

struct node
{
    int x,y,d;
};

int n,m,k,xs,ys,xf,yf;
int pos[Mk];
int ar[Mn][Mn];
vector< int > dv;
vector< int > dp[Mn][Mn];
queue< node > q;

inline int gcd(int a,int b)
{
    if (b == 0)
       return a;

    return gcd(b,a % b);
}

inline node make_node(int a,int b,int c)
{
    node aux;
    aux.x = a;aux.y = b;aux.d = c;

    return aux;
}

inline bool ok(int i,int j)
{
    return (i > 0 && j > 0 && i <= n && j <= m && ar[i][j]);
}

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 <= k;i++)
         if (k % i == 0)
            pos[i] = dv.size(),dv.push_back(i);

     for (int i = 1;i <= n;i++)
         for (int j = 1;j <= m;j++)
         {
             int val;
             scanf("%d",&val);
             ar[i][j] = gcd(k,val);
             dp[i][j].resize(dv.size());
         }

     q.push(make_node(xs,ys,pos[ar[xs][ys]]));
     dp[xs][ys][pos[ar[xs][ys]]] = 1;

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

         for (int it = 0;it < 4;it++)
         {
             int xx = act.x + dx[it],yy = act.y + dy[it],dd = pos[gcd(k,dv[act.d] * ar[act.x][act.y])];

             if (ok(xx,yy) && (dp[xx][yy][dd] == 0 || dp[xx][yy][dd] > dp[act.x][act.y][act.d] + 1))
             {
                 dp[xx][yy][dd] = dp[act.x][act.y][act.d] + 1;
                 q.push(make_node(xx,yy,dd));
             }
         }
     }

     printf("%d\n",dp[xf][yf][dv.size() - 1]);

  return 0;
}