Cod sursa(job #654119)

Utilizator mihaibogdan10Mihai Bogdan mihaibogdan10 Data 29 decembrie 2011 16:50:01
Problema Kdrum Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;

struct cell	{int x, y, lng, poz;};
int map[51][51], dist[51][51][200], K, N, M;
queue <cell> q;
vector <int> Div;

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

void DescompunePeK(){
	for (int i = 1; i <= K; i++)
		if (K % i == 0) Div.push_back(i);
}

int Poz(int divizor){
	for (int i = 0; i < Div.size(); i++)
		if (divizor == Div[i]) return i;
}

int main(){
	freopen("kdrum.in", "r", stdin), freopen("kdrum.out", "w", stdout);
	int x1, y1, x2, y2, i, j, p, x, y, x0, y0, factor0, lng, 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]); 
	
	for (i = 1; i <= N; i++)
		for (j = 1; j <= M; j++) 
			for (p = 0; p <= 200; p++) dist[i][j][p] = 0xfffffff;
	DescompunePeK();
	
	//dist[x][y][z] = lungimea minima a drumurilor care pana la divizibilitatea prin 
	//K mai au nevoie de al z-lea divizor al lui K si se incheie pe poz x,y
	
	q.push((cell){x1, y1, 1, Poz(K / CMMDC(K, map[x1][y1]))});
	while(!q.empty()){
		x0 = q.front().x, y0 = q.front().y, factor0 = Div[q.front().poz], lng = q.front().lng + 1;
		q.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 (lng < dist[x][y][Poz(factor)]){
						dist[x][y][Poz(factor)] = lng;
						q.push((cell){x, y, lng, Poz(factor)});
				}
			}
		}
	}
	
	printf("%d\n", dist[x2][y2][0]);
	return 0;
}