Pagini recente » Cod sursa (job #825396) | Cod sursa (job #820830) | Cod sursa (job #725634) | Cod sursa (job #2309856) | Cod sursa (job #1043163)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define infinite 9999999
using namespace std;
int n,m;
int parcurs[1010][1010];
int myDistance[1010][1010];
bool foundSolution;
bool solutionCertain;
ifstream in("barbar.in");
ofstream out("barbar.out");
int cost;
int middle;
struct pos
{
int i;
int j;
}A,start,finish;
queue <pos> myQueue;
vector <pos> dragons;
int caseAvailable;
void surrounder()
{
for(int i = 0; i <= m + 1; i++)
{
myDistance[0][i] = infinite;
myDistance[n+1][i] = infinite;
parcurs[0][i] = infinite;
parcurs[n+1][i] = infinite;
}
for(int i = 0; i <= n; i++)
{
myDistance[i][0] = infinite;
myDistance[i][m+1] = infinite;
parcurs[i][0] = infinite;
parcurs[i][m+1] = infinite;
}
}
void read()
{
char ch;
in>>n>>m;
surrounder();
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
myDistance[i][j] = infinite;
in>>ch;
if(ch == '.')
{
}
else
{
if(ch == '*')
{
parcurs[i][j] = infinite;
}
else
{
if(ch == 'D')
{
A.i = i;
A.j = j;
dragons.push_back(A);
myDistance[i][j] = 0;
parcurs[i][j] = infinite;
}
else
{
if(ch == 'I')
{
start.i = i;
start.j = j;
}
else
{
finish.i = i;
finish.j = j;
}
}
}
}
}
}
}
void queueUp(int i, int j)
{
if(parcurs[i-1][j] < caseAvailable)
{
parcurs[i-1][j] = caseAvailable;
if((myDistance[i-1][j] > myDistance[i][j] + 1) || myDistance[i-1][j] == 0)
{
parcurs[i-1][j] = caseAvailable;
A.i = i-1;
A.j = j;
myDistance[i-1][j] = myDistance[i][j] + 1;
myQueue.push(A);
}
}
}
void queueMiddle(int i, int j)
{
if(parcurs[i][j-1] < caseAvailable)
{
parcurs[i][j-1] = caseAvailable;
if( myDistance[i][j-1] > myDistance[i][j] + 1 )
{
A.i = i;
A.j = j-1;
myQueue.push(A);
parcurs[i][j-1] = caseAvailable;
myDistance[i][j-1] = myDistance[i][j] + 1;
}
}
if(parcurs[i][j+1] < caseAvailable )
{
if(myDistance[i][j+1] > myDistance[i][j] + 1)
{
A.i = i;
A.j = j+1;
myQueue.push(A);
parcurs[i][j+1] = caseAvailable;
myDistance[i][j+1] = myDistance[i][j] + 1;
}
}
}
void queueDown(int i, int j)
{
if(parcurs[i+1][j] < caseAvailable)
{
if(myDistance[i+1][j] > myDistance[i][j] + 1)
{
parcurs[i+1][j] = caseAvailable;
myDistance[i+1][j] = myDistance[i][j] + 1;
A.i = i+1;
A.j = j;
myQueue.push(A);
}
}
}
void queueMyNeighbours(int i, int j)
{
queueUp(i,j);
queueMiddle(i,j);
queueDown(i,j);
}
void setmyDistance()
{
pos aux;
while(myQueue.empty() == false)
{
aux = myQueue.front();
myQueue.pop();
queueMyNeighbours(aux.i,aux.j);
}
}
void dragonIt()
{
for(int i = 0; i < dragons.size(); i++)
{
caseAvailable++ ;
myQueue.push(dragons[i]);
setmyDistance();
}
}
void df(int i, int j)
{
parcurs[i][j] = caseAvailable;
if(i == finish.i && j == finish.j)
{
foundSolution = true;
}
else
{
if(foundSolution == false)
{
if(parcurs[i-1][j] < caseAvailable && myDistance[i-1][j] >= middle)
{
df(i-1,j);
}
if(parcurs[i+1][j] < caseAvailable && myDistance[i+1][j] >= middle)
{
df(i+1,j);
}
if(parcurs[i][j-1] < caseAvailable && myDistance[i][j-1] >= middle )
{
df(i,j-1);
}
if(parcurs[i][j+1] < caseAvailable && myDistance[i][j+1] >= middle)
{
df(i, j+1);
}
}
}
}
int bsc()
{
int step,i;
for (step = 1; step < n + m + 1; step <<= 1)
{
}
for (i = 0; step; step >>= 1)
{
foundSolution = false;
if(i + step < n*m+1)
{
foundSolution = false;
middle = i + step;
df(start.i,start.j);
if(foundSolution == true)
{
i = i + step;
solutionCertain = true;
}
}
}
return i;
}
void writeMatrix()
{
for(int i = 1 ; i<=n; i++)
{
for(int j = 1; j <= m; j++)
{
if(myDistance[i][j] == infinite)
{
out<<"* ";
}
else
out<<myDistance[i][j]<<" ";
}
out<<endl;
}
}
void solve()
{
dragonIt();
caseAvailable++;
middle = bsc();
}
void write()
{
if (solutionCertain == false)
{
out<<-1;
}
else
{
out<<middle;
}
}
main()
{
read();
solve();
write();
}