Cod sursa(job #483605)

Utilizator dcm9000Dinu Cristian Mircea - UPB dcm9000 Data 9 septembrie 2010 13:40:56
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <map>

using namespace std;

#define FILE_IN "barbar.in"
#define FILE_OUT "barbar.out"

#define STRIDE 1024

int R, C;
char MAP[1024*STRIDE];
short DIST[1024*STRIDE];
int NOD_IN;
int NOD_OUT;

void incarcaHarta()
{
	ifstream fisIn(FILE_IN);
	fisIn >> R >> C;
	for (int i=0; i<R; i++)
	{
		int baza = (i+1)*STRIDE;
		
		fisIn >> (MAP+baza+1);
		MAP[baza] = '*';
		MAP[baza+C+1] = '*';
		MAP[baza+C+2] = 0;

		char* pos = strchr(MAP+baza, 'I');
		if (pos) NOD_IN = pos-MAP;

		pos = strchr(MAP+baza, 'O');
		if (pos) NOD_OUT = pos-MAP;
	}

	memset(MAP, '*', C+2); MAP[C+2] = 0;
	memset(MAP+(R+1)*STRIDE, '*', C+2); MAP[(R+1)*STRIDE+C+2] = 0;
}

static inline int min(int a, int b)
{
	return a<b ? a : b;
}

void calcDist()
{
	int ptr, ptrMax;
	
	memset(DIST, 0x3F, sizeof(short)*STRIDE*(R+2));
	
	for (int i=1; i<=R; i++)
	{
		int baza = i*STRIDE;

		for (ptr=baza+1, ptrMax=baza+C; ptr<=ptrMax; ptr++)
		{
			if (MAP[ptr] == 'D')
				DIST[ptr] = 0;
			else
				DIST[ptr] = min(DIST[ptr-1], DIST[ptr-STRIDE])+1;
		}
		
		for (ptr=baza+C, ptrMax=baza+1; ptr>=ptrMax; ptr--)
			DIST[ptr] = min(DIST[ptr], DIST[ptr+1]+1);
	}

	for (int i=R; i>=1; i--)
	{
		int baza = i*STRIDE;

		for (ptr=baza+1, ptrMax=baza+C; ptr<=ptrMax; ptr++)
			DIST[ptr] = min(DIST[ptr], DIST[ptr+STRIDE]+1);
	}
}

int main()
{
	incarcaHarta();
	calcDist();

	multimap<short, int> coada;
	multimap<short, int>::iterator it;

	coada.insert(pair<short,int>(DIST[NOD_IN], NOD_IN));

	short best = 10000;
	while (!coada.empty())
	{
		it = --coada.end();
		short dist = it->first;
		int nod = it->second;
		coada.erase(it);

		if (dist < best) best = dist;
		
		MAP[nod] = '*';
		if (nod == NOD_OUT) break;

		if (MAP[nod-STRIDE] != '*') coada.insert(pair<short,int>(DIST[nod-STRIDE], nod-STRIDE));
		if (MAP[nod+STRIDE] != '*') coada.insert(pair<short,int>(DIST[nod+STRIDE], nod+STRIDE));
		if (MAP[nod-1] != '*') coada.insert(pair<short,int>(DIST[nod-1], nod-1));
		if (MAP[nod+1] != '*') coada.insert(pair<short,int>(DIST[nod+1], nod+1));
	}

	ofstream fisOut(FILE_OUT);
	fisOut << ((MAP[NOD_OUT] == '*') ? best : -1);
}