Cod sursa(job #467761)

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

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

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

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

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


int n, m, dk, a[51][51], dv[151];
int d[51][51][151];
pair<int, int> 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 (int i = 1; i <= n; ++i)
		for (int 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 (int 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 (int 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)
			{
				int 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 (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			for (int k = 1; k <= dv[0]; ++k)
				d[i][j][k] = INF;
}