Cod sursa(job #255566)

Utilizator ProtomanAndrei Purice Protoman Data 9 februarie 2009 23:04:30
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
// pnm hibride:)
#include <algorithm>
#include <stdio.h>
#include <vector>

#define pb push_back

using namespace std;

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

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

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

	return nr1;
}

void findWay()
{
	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++)
	{
		int i = queBfs[queSt].x, j = queBfs[queSt].y;

		for (int dir = 0; dir < 4; dir++)
		{
			if (i + dirI[dir] < 1 || i + dirI[dir] > n 
				|| j + dirJ[dir] < 1 || j + dirJ[dir] > m
				|| !matNr[i + dirI[dir]][j + dirJ[dir]])
				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)
			{
				printf("%d\n", 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 (matNr[i][j])
				matNr[i][j] = gcd(matNr[i][j], k);
		}

	findWay();

	fclose(stdin);
	fclose(stdout);
	return 0;
}