Cod sursa(job #254715)

Utilizator tvladTataranu Vlad tvlad Data 7 februarie 2009 13:51:27
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2009, clasele 9-10, ziua 2 Marime 3 kb
#include <cstdio>
#include <queue>
using namespace std;

const int NP = 8;
const int NMAX = 50;
const int ND = 4;
const pair<int,int> D[ND] = { make_pair(0,1), make_pair(1,0), make_pair(0,-1), make_pair(-1,0) };

int n, m, k;
pair<int,int> start,end;
int np, tpr[NP], tgt[NP];
int mat[NMAX][NMAX][NP];
bool ok[NMAX][NMAX];

void descompune ( int x, int v[], int e[], int &np ) {
	np = 0;
	if (x % 2 == 0) {
		v[np] = 2;
		for (e[np] = 0; x % 2 == 0; x /= 2, ++e[np]);
		++np;
	}
	for (int p = 3; p <= x; p += 2) {
		if (x % p == 0) {
			v[np] = p;
			for (e[np] = 0; x % p == 0; x /= p, ++e[np]);
			++np;
		}
	}
}
void descompune ( int x, int v[] ) {
	for (int i = 0; i < np; ++i)
		for (v[i] = 0; x % tpr[i] == 0; x /= tpr[i], ++v[i]);
}

struct queue_elem {
	pair<int,int> loc;
	int level;
	int d[NP];
	queue_elem() {};
	queue_elem ( pair<int,int> a ) {
		loc = a;
		level = 1;
		for (int i = 0; i < NP; ++i) d[i] = 0;
	};
};
void add ( queue_elem a, pair<int,int> b, queue_elem &rez ) {
	rez.loc.first = a.loc.first + b.first;
	rez.loc.second = a.loc.second + b.second;
	if (rez.loc.first < 0 || rez.loc.first >= n ||
		rez.loc.second < 0 || rez.loc.second >= m ||
		!ok[rez.loc.first][rez.loc.second]) {
		rez.level = -1;
		return;
	}
	rez.level = a.level + 1;
	for (int i = 0; i < np; ++i) {
		rez.d[i] = a.d[i] + mat[rez.loc.first][rez.loc.second][i];
	}
}
bool comp_ge ( int a[], int b[] ) {
	for (int i = 0; i < np; ++i)
		if (a[i] < b[i])
			return false;
	return true;
}
void trace ( queue_elem &a ) {
	printf("Level %d \ Loc: %d,%d \ Gain: %d%d%d\n",a.level,a.loc.first,a.loc.second,a.d[0],a.d[1],a.d[2]);
}
int bf() {
	queue<queue_elem> Q;
	queue_elem st(start);
	for (Q.push(st); !Q.empty(); Q.pop()) {
		for (int i = 0; i < ND; ++i) {
			queue_elem next;
			add(Q.front(), D[i], next);
			if (next.level > -1) {
				//trace(next);
				if (next.loc == end && comp_ge(next.d, tgt)) {
					return next.level;
				} else {
					Q.push(next);
				}
			}
		}
	}
	return -1;
}

int bf_prost() {
	queue<queue_elem> Q;
	queue_elem st(start);
	for (Q.push(st); !Q.empty(); Q.pop()) {
		for (int i = 0; i < ND; ++i) {
			queue_elem next;
			add(Q.front(), D[i], next);
			if (next.level > -1) {
				//trace(next);
				if (next.loc == end) {
					return next.level;
				} else {
					ok[next.loc.first][next.loc.second] = false;
					Q.push(next);
				}
			}
		}
	}
	return -1;
}

int main() {
	freopen("kdrum.in","rt",stdin);
	freopen("kdrum.out","wt",stdout);
	scanf("%d %d %d",&n,&m,&k);
	descompune(k,tpr,tgt,np);
	scanf("%d %d %d %d",&start.first,&start.second,&end.first,&end.second);
	--start.first;
	--start.second;
	--end.first;
	--end.second;
	for (int i = 0; i < n; ++i) {
		for (int j = 0, x; j < m; ++j) {
			scanf("%d",&x);
			if (x == 0) {
				ok[i][j] = false;
			} else {
				ok[i][j] = true;
				descompune(x,mat[i][j]);
			}
		}
	}
	if (k == 1)
		printf("%d\n",bf_prost()); else
		printf("%d\n",bf());
	return 0;
}