Pagini recente » Cod sursa (job #1085797) | Cod sursa (job #1831324) | Cod sursa (job #1213686) | Cod sursa (job #2744360) | Cod sursa (job #483627)
Cod sursa(job #483627)
#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 if (MAP[ptr] == '*')
DIST[ptr] = 0x3F3F;
else
DIST[ptr] = min(DIST[ptr-1], DIST[ptr-STRIDE])+1;
for (ptr=baza+C, ptrMax=baza+1; ptr>=ptrMax; ptr--)
if (MAP[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++)
if (MAP[ptr] != '*')
DIST[ptr] = min(DIST[ptr], DIST[ptr+STRIDE]+1);
}
}
void curataHarta()
{
int ptr, ptrMax;
for (int i=1; i<=R; i++)
for (ptr=i*STRIDE+1,ptrMax=i*STRIDE+C; ptr<=ptrMax; ptr++)
switch (MAP[ptr])
{
case 'I': case 'O': case 'D': MAP[ptr] = '.'; break;
}
}
int main()
{
incarcaHarta();
calcDist();
curataHarta();
multimap<short, int> coada;
multimap<short, int>::iterator it;
coada.insert(pair<short,int>(DIST[NOD_IN], NOD_IN));
MAP[NOD_IN] = 'X';
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;
if (nod == NOD_OUT) break;
if (MAP[nod-STRIDE] == '.') { coada.insert(pair<short,int>(DIST[nod-STRIDE], nod-STRIDE)); MAP[nod-STRIDE]='X'; }
if (MAP[nod+STRIDE] == '.') { coada.insert(pair<short,int>(DIST[nod+STRIDE], nod+STRIDE)); MAP[nod+STRIDE]='X'; }
if (MAP[nod-1] == '.') { coada.insert(pair<short,int>(DIST[nod-1], nod-1)); MAP[nod-1]='X'; }
if (MAP[nod+1] == '.') { coada.insert(pair<short,int>(DIST[nod+1], nod+1)); MAP[nod+1]='X'; }
}
ofstream fisOut(FILE_OUT);
fisOut << ((MAP[NOD_OUT] == 'X') ? best : -1);
}