Cod sursa(job #653862)

Utilizator mihaibogdan10Mihai Bogdan mihaibogdan10 Data 29 decembrie 2011 02:40:37
Problema Kdrum Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 kb
#include<cstdio>
#include<queue>
using namespace std;

struct nod{int x, y, lng, factor;};
int map[51][51], drumuri[51][51], K, N, M,
prim[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109};
queue <nod> coada;

int ABS(int a){
	return a > 0  ? a : -a;
}

int CMMDC(int a, int b){
	if (a < b) a = a + b - (b = a);
	int r = a % b;
	while (r != 0)	a = b, b = r, r = a % b;
	return b;
}

int main(){
	freopen("kdrum.in", "r", stdin), freopen("kdrum.out", "w", stdout);
	int x1, y1, x2, y2, i, j, x, y, x0, y0, factor0, lng0, factor;
	int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
	scanf("%d %d %d %d %d %d %d", &N, &M, &K, &x1, &y1, &x2, &y2);
	
	for (i = 1; i <= N; i++)
		for (j = 1; j <= M; j++) scanf("%d", &map[i][j]), drumuri[i][j] = 0xfffffff;
	
	//caut drumurile de lungime minima care au produsul div cu K, care se incheie pe poz x, y
	coada.push((nod){x1, y1, 1, K / CMMDC(K, map[x1][y1])});
	while(!coada.empty()){
		x0 = coada.front().x, y0 = coada.front().y, factor0 = coada.front().factor, lng0 = coada.front().lng;
		coada.pop();
		
		for (i = 0; i < 4; i++){
			x = x0 + dx[i], y = y0 + dy[i];			
			if (0 < x && x <= N && 0 < y && y <= M && map[x][y] ){
				factor = factor0 / CMMDC(factor0, map[x][y]);
				if (lng0 + 1 < drumuri[x][y] && factor == 1)
						drumuri[x][y] = lng0 + 1;
				else if(factor > 1 && lng0 < N * M) coada.push((nod){x, y, lng0 + 1, factor});
			}
		}
	}
	
	int min = 0xfffffff, dist;
	for (i = 1; i <= N; i++)
		for (j = 1; j <= M; j++){
			dist = drumuri[i][j] + ABS(i - x2) + ABS(j - x2);
			if (min > dist) min = dist;
		}
	printf("%d\n", min);
	
	return 0;
}