Cod sursa(job #254256)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 7 februarie 2009 04:01:12
Problema Kdrum Scor Ascuns
Compilator cpp Status done
Runda Marime 2.01 kb
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <stdlib.h>

using namespace std;

#define MAXN 60
#define MAXK 12010
#define MAXX 190010
#define MAXD 75
#define MAXL 4
#define INF 30000
#define ll long long

int N, M, K, L, NR;
int x1, y1, x2, y2;
int A[MAXN][MAXN];
int D[MAXD];
char Sx[MAXX], Sy[MAXX];
int Sz[MAXX];
short V[MAXN][MAXN][MAXD];
const int dirx[MAXD] = {-1, 1, 0, 0};
const int diry[MAXD] = {0, 0, -1, 1};
short Hash[MAXK];

inline int GCD(int A, int B)
{
	int aux;

	while (B)
	{
		aux = A%B;
		A = B;
		B = aux;
	}

	return int(A);
}

void dcmp(int K)
{
	int i;

	for (i = 1; i*i <= K; i++)
		if (K % i == 0) D[++NR] = i;

	for (i = NR - (D[NR]*D[NR]==K); i>0; i--) D[++NR] = K / D[i];

	for (i = 1; i <= NR; i++) Hash[D[i]] = i;
}

void BFS(int x1, int y1, int x2, int y2)
{
	int i, j, k, cx, cy, newd;
	
	for (i = 1; i <= N; i++)
		for (j = 1; j <= M; j++)
			for (k = 1; k <= NR; k++) V[i][j][k] = INF;

	L = 1;
	Sx[L] = x1, Sy[L] = y1, Sz[L] = 1;
	V[x1][y1][1] = 1;

	for (i = 1; i <= L; i++)
		for (j = 0; j < MAXD; j++)
		{
			cx = Sx[i] + dirx[j];
			cy = Sy[i] + diry[j];

			if (cx>0 && cx<=N && cy>0 && cy<=M && A[cx][cy])
			{
				newd = Hash[ GCD(K, 1LL * D[Sz[i]] * A[cx][cy])];

				if (V[int(Sx[i])][int(Sy[i])][Sz[i]] + 1 < V[cx][cy][newd])
				{
					V[cx][cy][newd] = V[int(Sx[i])][int(Sy[i])][Sz[i]] + 1;
					L++;
					Sx[L] = cx, Sy[L] = cy, Sz[L] = newd;
					if (Sx[L] == x2 && Sy[L] == y2 && Sz[L] == K) return;
				}
			}
		}
}

int main()
{
	freopen("kdrum.in", "r", stdin);
	freopen("kdrum.out", "w", stdout);

	int i, j;

	scanf("%d %d %d ", &N, &M, &K);

	assert(1<=N && N<=50);
	assert(1<=M && M<=50);
	assert(1<=K && K<=12000);

	scanf("%d %d %d %d ", &x1, &y1, &x2, &y2);

	assert(1<=x1 && x1<=N);
	assert(1<=x2 && x2<=N);
	assert(1<=y1 && y1<=M);
	assert(1<=y2 && y2<=M);

	for (i = 1; i <= N; i++)
		for (j = 1; j <= M; j++) 
		{
			scanf("%d ", &A[i][j]);

			assert(0<=A[i][j] && A[i][j]<=10000);
		}

	dcmp(K);

	BFS(x1, y1, x2, y2);

	printf("%d\n", V[x2][y2][NR]);

	return 0;
}