Pagini recente » Cod sursa (job #2941575) | Cod sursa (job #224898) | Cod sursa (job #1292509) | Cod sursa (job #1774921) | Cod sursa (job #1026844)
#include <fstream>
#include <vector>
#include <queue>
#include <cmath>
#define MAXINT 0x7FFFFFFF
using namespace std;
struct ptemnita
{
char c;
int distanta_dragon;
bool vizitat;
};
struct punct
{
int x,y;
punct()
{
x = y = 0;
}
punct(int a,int b)
{
x = a;
y = b;
}
bool operator ==(const punct &alt)
{
return (alt.x == x && alt.y == y);
}
};
ptemnita **temnita;
punct start,destinatie;
int r,c;
inline void deviziteaza()
{
int i,j;
for(i=0;i<r;++i)
for(j=0;j<c;++j)
temnita[i][j].vizitat = false;
}
void flood(int x,int y,int distanta)
{
if(x < 0 || y < 0 || x >= r || y >= c)
return;
if(temnita[x][y].distanta_dragon <= distanta || temnita[x][y].c == '*')
return;
temnita[x][y].distanta_dragon = distanta;
++distanta;
flood(x - 1,y,distanta);
flood(x + 1,y,distanta);
flood(x,y - 1,distanta);
flood(x,y + 1,distanta);
}
bool parcurge(int apropiere)
{
deviziteaza();
queue <punct> puncte_nevizitate;
punct locatie_curenta;
puncte_nevizitate.push(punct(start.x,start.y));
do
{
locatie_curenta = puncte_nevizitate.front();
puncte_nevizitate.pop();
if(temnita[locatie_curenta.x][locatie_curenta.y].vizitat == true || temnita[locatie_curenta.x][locatie_curenta.y].distanta_dragon < apropiere || temnita[locatie_curenta.x][locatie_curenta.y].c == '*')
continue;
temnita[locatie_curenta.x][locatie_curenta.y].vizitat = true;
if(locatie_curenta == destinatie)
return true;
if(locatie_curenta.x > 0)
puncte_nevizitate.push(punct(locatie_curenta.x - 1,locatie_curenta.y));
if(locatie_curenta.x < r - 1)
puncte_nevizitate.push(punct(locatie_curenta.x + 1,locatie_curenta.y));
if(locatie_curenta.y > 0)
puncte_nevizitate.push(punct(locatie_curenta.x,locatie_curenta.y - 1));
if(locatie_curenta.y < c - 1)
puncte_nevizitate.push(punct(locatie_curenta.x,locatie_curenta.y + 1));
}
while(!puncte_nevizitate.empty());
return false;
}
int main()
{
ifstream f("barbar.in");
f>>r>>c;
temnita = new ptemnita*[r];
vector <punct> dragoni;
for(int i=0;i<r;++i)
{
temnita[i] = new ptemnita[c];
}
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
{
temnita[i][j].distanta_dragon = MAXINT;
f>>temnita[i][j].c;
switch(temnita[i][j].c)
{
case 'D':
dragoni.push_back(punct(i,j));
break;
case 'I':
start.x = i;
start.y = j;
break;
case 'O':
destinatie.x = i;
destinatie.y = j;
break;
}
if(temnita[i][j].c == 'D')
dragoni.push_back(punct(i,j));
}
for(vector<punct>::iterator it=dragoni.begin();it != dragoni.end();it++)
{
flood(it->x,it->y,0);
}
ofstream g("barbar.out");
if(!parcurge(0))
g<<-1;
else
{
int dist_max = min(temnita[start.x][start.y].distanta_dragon,temnita[destinatie.x][destinatie.y].distanta_dragon);
int dist_min = 0;
int incercare;
while(abs(dist_max - dist_min) > 1)
{
incercare = (dist_min + dist_max) / 2;
if(parcurge(incercare))
dist_min = incercare;
else
dist_max = incercare;
}
if(dist_max != dist_min)
{
if(parcurge(dist_max))
g<<dist_max;
else
g<<dist_min;
}
else
g<<dist_min;
}
g.close();
return 0;
}