Cod sursa(job #324955)

Utilizator Mishu91Andrei Misarca Mishu91 Data 18 iunie 2009 10:54:28
Problema Kdrum Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.46 kb
#include <cstdio>
#include <queue>

using namespace std;

#define MAX_N 55
#define MAX_K 12005
#define MAX_D 505

const int dx[] = {-1, 0, 0, 1},
		  dy[] = { 0, 1,-1, 0};	

int N, M, K, Nd, Xf, Yf, Xs, Ys;
int A[MAX_N][MAX_N], D[MAX_N][MAX_N][MAX_D];
int P[MAX_K], L[MAX_K];

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

void citire()
{
	scanf("%d %d %d\n%d %d %d %d", &N, &M, &K, &Xs, &Ys, &Xf, &Yf);
	
	for(int i = 1; i <= N; ++i)
		for(int j = 1; j <= M; ++j)
			scanf("%d ",A[i]+j);
}

void pre()
{
	for(int i = 1; i <= K; ++i)
		if(K % i == 0)
		{
			P[i] = ++Nd;
			L[Nd] = i;
		}
}

void solve()
{
	queue <pair <int, int> > Q;
	D[Xs][Ys][P[gcd(A[Xs][Ys], K)]] = 1;
	for(Q.push(make_pair((Xs << 6) + Ys, P[gcd(A[Xs][Ys], K)])); !Q.empty(); Q.pop())
	{
		int i = Q.front().first >> 6;
		int j = Q.front().first & 63;
		int p = Q.front().second;
		int d = L[p];
		
		for(int k = 0; k < 4; ++k)
		{
			int _i = i + dx[k];
			int _j = j + dy[k];
			if(!A[_i][_j]) continue;
			
			int _d = gcd(A[_i][_j], K);
			int dc = P[gcd(d*_d, K)];
			
			if(D[_i][_j][dc]) continue;
			
			D[_i][_j][dc] = D[i][j][p] + 1;
			if(_i == Xf && _j == Yf && dc == Nd)
			{
				printf("%d\n",D[_i][_j][dc]);
				return;
			}				
			
			Q.push(make_pair((_i << 6) + _j, dc));
		}
	}		
}

int main()
{
	freopen("kdrum.in","rt",stdin);
	freopen("kdrum.out","wt",stdout);
	
	citire();
	pre();
	solve();
}