Cod sursa(job #467760)

Utilizator darrenRares Buhai darren Data 30 iunie 2010 13:55:01
Problema Kdrum Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include<fstream>
#include<algorithm>
#include<limits>
#include<queue>
using namespace std;

const int INF = INT_MAX;
const short d1[] = {1, 0, -1, 0},
            d2[] = {0, 1, 0, -1};

struct spoint
{
	pair<short, short> pos;
	short div;
	
	spoint() {}
	spoint(pair<short, short> _pos, short _div)
	{
		pos = _pos, div = _div;
	}
};

void comp_div();
void comp_sol();
void init_d();

inline short cmmdc(short _a, short _b)
{
	if (_b == 0) return _a;
	return cmmdc(_b, _a % _b);
}


short n, m, dk, a[51][51], dv[151];
int d[51][51][151];
pair<short, short> p1, p2;
queue<spoint> q;

int main()
{
	ifstream fin("kdrum.in");
	ofstream fout("kdrum.out");
	fin >> n >> m >> dk
	    >> p1.first >> p1.second
		>> p2.first >> p2.second;
	for (short i = 1; i <= n; ++i)
		for (short j = 1; j <= m; ++j)
		{
			fin >> a[i][j];
			if (a[i][j] != 0)
				a[i][j] = cmmdc(a[i][j], dk);
		}
	comp_div();
	comp_sol();
	fout << d[p2.first][p2.second][dv[0]];
}

void comp_div()
{
	for (short i = 1; i <= dk; ++i)
		if (dk % i == 0)
			dv[++dv[0]] = i;
}

void comp_sol()
{
	init_d();
	
	q.push(spoint(p1, 1));
	d[p1.first][p1.second][1] = 1;
	
	while (!q.empty())
	{
		spoint now = q.front(); q.pop();
		for (short i = 0; i < 4; ++i)
			if (now.pos.first + d1[i] >= 1 && now.pos.second + d2[i] >= 1 && now.pos.first + d1[i] <= n && now.pos.second + d2[i] <= m && a[now.pos.first + d1[i]][now.pos.second + d2[i]] != 0)
			{
				short aux_val = cmmdc(dv[now.div] * a[now.pos.first + d1[i]][now.pos.second + d2[i]], dk);
				aux_val = upper_bound(dv + 1, dv + dv[0] + 1, aux_val) - (dv + 1);
				
				spoint aux(make_pair(now.pos.first + d1[i], now.pos.second + d2[i]), aux_val);
				if (d[now.pos.first][now.pos.second][now.div] + 1 < d[aux.pos.first][aux.pos.second][aux.div])
				{
					d[aux.pos.first][aux.pos.second][aux.div] = d[now.pos.first][now.pos.second][now.div] + 1;
					q.push(aux);
				}
			}
	}
}

void init_d()
{
	for (short i = 1; i <= n; ++i)
		for (short j = 1; j <= m; ++j)
			for (short k = 1; k <= dv[0]; ++k)
				d[i][j][k] = INF;
}