Cod sursa(job #773398)

Utilizator danalex97Dan H Alexandru danalex97 Data 1 august 2012 17:01:33
Problema Barbar Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;

#define Nmax 1011
#define x first
#define y second

#define cost first
#define k1 second.first
#define k2 second.second

ifstream F("barbar.in");
ofstream G("barbar.out");

typedef pair<int,int> Pair;
typedef pair<int,Pair> Grupe;

queue< Pair > Q;
priority_queue< Grupe,vector<Grupe> > H;

int D[Nmax][Nmax];
int Marked[Nmax][Nmax];
int Max;

int Lee[Nmax][Nmax];
queue< Pair > Q2;

char Str[Nmax*Nmax*10];
int N,M,Act;

Pair Start,End;

int Dx[]={ 0 , -1 , 1 , 0 ,  0 };
int Dy[]={ 0 ,  0 , 0 , 1 , -1 };

void Get(int i,int j)
{
	while ( Str[Act]=='\n' ) ++Act;
	switch( Str[Act] )
	{
		case 'I':
			++Act;
			Start.x=i;
			Start.y=i;
			break;
		case 'O':
			++Act;
			End.x=i;
			End.y=i;
			break;
		case '.':
			++Act;
			break;
		case 'D':
			D[i][j]=-1;
			++Act;
			Q.push( make_pair(i,j) );
			break;
		case '*':
			D[i][j]=-1;
			++Act;
			break;
	}
}

inline int in(int x,int y)
{
	if ( x>0 && x<=N && y>0 && y<=M ) 
		return 1;
	return 0;
}

void Neighbour( Grupe Nod )
{
	for (int i=1;i<5;++i)
		if ( in(Nod.k1+Dx[i],Nod.k2+Dy[i]) )
			if ( D[ Nod.k1+Dx[i] ][ Nod.k2+Dy[i] ]!=-1 && ! Marked[ Nod.k1+Dx[i] ][ Nod.k2+Dy[i] ])
				H.push( make_pair( D[ Nod.k1+Dx[i] ][ Nod.k2+Dy[i] ] , make_pair( Nod.k1+Dx[i] , Nod.k2+Dy[i] ) ) );
}

bool Ver()
{
	Q2.push( Start );
	while ( Q2.size() )
	{
		int i=Q2.front().x;
		int j=Q2.front().y;
		
		for (int k=1;k<5;++k)
			if ( in(i+Dx[k], j+Dy[k]) )
				if ( !Lee[ i+Dx[k] ][ j+Dy[k] ] && !D[ i+Dx[k] ][ j+Dy[k] ] )
				{
					Lee[ i+Dx[k] ][ j+Dy[k] ]=1;
					Q2.push( make_pair(i+Dx[k],j+Dy[k]) );
				}
		
		Q2.pop();
	}
	return Lee[End.x][End.y];
}

int main()
{
	F>>N>>M;
	F.getline(Str,Nmax*Nmax,EOF);
	
	for (int i=1;i<=N;++i)
		for (int j=1;j<=N;++j)
			Get(i,j);
	
	if ( ! Ver() )
	{
		G<<"-1\n";
		return 0;
	}		
	
	while ( Q.size() )
	{
		int i=Q.front().x;
		int j=Q.front().y;
		
		for (int k=1;k<5;++k)
			if ( in(i+Dx[k], j+Dy[k]) )
				if ( !D[ i+Dx[k] ][ j+Dy[k] ] )
				{
					D[ i+Dx[k] ][ j+Dy[k] ]=(D[i][j]==-1 ? 0 : D[i][j])+1;
					Q.push( make_pair(i+Dx[k],j+Dy[k]) );
				}
		
		Q.pop();
	}
	
	H.push( make_pair(D[Start.x][Start.y],Start) );
	Marked[Start.x][Start.y]=D[Start.x][Start.y];
	Max=H.top().cost;
	
	while ( !Marked[End.x][End.y] )
	{
		Grupe Nod=H.top();
		H.pop();
		
		Neighbour( Nod );
		
		Marked[H.top().k1][H.top().k2]=H.top().cost;
		Max=min( Max,H.top().cost );
	}
	
	G<<Max<<'\n';
}