Cod sursa(job #254674)

Utilizator ProtomanAndrei Purice Protoman Data 7 februarie 2009 13:41:18
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 2 Marime 2.32 kb
// pnm hibride:)
#include <algorithm>
#include <stdio.h>
#include <vector>

#define pb push_back

using namespace std;

struct pozitie
{
	short x, y, divz;
	int pasi;
};

int dirI[] = {-1, 0, 0, 1};
int dirJ[] = {0, -1, 1, 0};
int n, m, k, sol, x1, x2, y1, y2;
int matNr[60][60];
vector <int> matVizDiv[60][60];
vector <pozitie> queBfs;

void leeSimplu()
{
	int matAc[60][60];

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			matAc[i][j] = 2510;
	matAc[x1][y1] = 1;

	for (int act = 1; matAc[x2][y2] == 2510; act++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				if (matAc[i][j] == act)
					for (int dir = 0; dir < 4; dir++)
						matAc[i + dirI[dir]][j + dirJ[dir]] = min(matAc[i][j] + 1, matAc[i + dirI[dir]][j + dirJ[dir]]);
	sol = matAc[x2][y2];
}

int gcd(long long nr1, long long nr2)
{
	while (nr2)
	{
		long long nrAux = nr1 % nr2;
		nr1 = nr2;
		nr2 = nrAux;
	}

	return (int) nr1;
}

void leeMajor()
{
	int queSt = 0, queFn = 0;
	pozitie AUX;
	AUX.x = x1;
	AUX.y = y1;
	AUX.divz = gcd(k, matNr[x1][y1]);
	AUX.pasi = 1;
	queBfs.pb(AUX);

	for (; queSt <= queFn; queSt++)
	{
		for (int dir = 0; dir < 4; dir++)
		{
			int i = queBfs[queSt].x, j = queBfs[queSt].y;
			if (i + dirI[dir] < 1 || i + dirI[dir] > n 
				|| j + dirJ[dir] < 1 || j + dirJ[dir] > m
				|| !matNr[i][j])
				continue;

			int ok = 1, divAj = gcd(queBfs[queSt].divz * matNr[i + dirI[dir]][j + dirJ[dir]], k);

			for (int divi = 0; divi < matVizDiv[i + dirI[dir]][j + dirJ[dir]].size(); divi++)
				if (divAj == matVizDiv[i + dirI[dir]][j + dirJ[dir]][divi])
				{
					ok = 0;
					break;
				}
	
			AUX.x = i + dirI[dir];
			AUX.y = j + dirJ[dir];
			AUX.divz = divAj;
			AUX.pasi = queBfs[queSt].pasi + 1;
			if (AUX.x == x2 && AUX.y == y2 && AUX.divz == k)
			{
				sol = AUX.pasi;
				return;
			}

			if (ok)
			{
				queBfs.pb(AUX);
				queFn++;
			}
		}
	}
}

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

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

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &matNr[i][j]);

	if (k == 1)
		leeSimplu();
	else leeMajor();

	printf("%d", sol);
	fclose(stdin);
	fclose(stdout);
	return 0;
}