Cod sursa(job #764759)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 6 iulie 2012 11:07:51
Problema Barbar Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include<fstream>
#include<queue>
#include<cmath>
using namespace std;
int n,m,sol;
int mat[1010][1010],dist[1010][1010];
struct Pozitie{int x,y;};
Pozitie start,final;
queue <Pozitie> Q;
bool viz[1010][1010];

int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};

inline void Citire()
{
	int i,j;
	Pozitie aux;
	char s[1010];
	ifstream fin("barbar.in");
	fin>>n>>m;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			dist[i][j]=2000000000;
	for(i=1;i<=n;i++)
	{
		fin>>(s+1);
		for(j=1;j<=m;j++)
		{
			if(s[j]=='.')
				continue;
			if(s[j]=='*')
				mat[i][j]=-1;
			if(s[j]=='D')
			{
				aux.x=i;
				aux.y=j;
				Q.push(aux);
				dist[i][j]=0;
				continue;
			}
			if(s[j]=='I')
			{
				start.x=i;
				start.y=j;
				continue;
			}
			final.x=i;
			final.y=j;
		}
	}
	fin.close();
}

inline void Calculare_Distante_Dragoni()
{
	int k;
	Pozitie aux,poz;
	while(!Q.empty())
	{
		aux=Q.front();
		Q.pop();
		for(k=0;k<4;k++)
		{
			poz.x=aux.x+dx[k];
			poz.y=aux.y+dy[k];
			if(mat[poz.x][poz.y]==0 && dist[poz.x][poz.y]>dist[aux.x][aux.y]+1)
			{
				dist[poz.x][poz.y]=dist[aux.x][aux.y]+1;
				Q.push(poz);
			}
		}
	}
}

inline bool Posibil(int D)
{
	int i,j,k;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			viz[i][j]=false;
	while(!Q.empty())
		Q.pop();
	Pozitie aux,poz;
	Q.push(start);
	viz[start.x][start.y]=true;
	while(!Q.empty())
	{
		aux=Q.front();
		Q.pop();
		if(aux.x==final.x && aux.y==final.y)
			return true;
		for(k=0;k<4;k++)
		{
			poz.x=aux.x+dx[k];
			poz.y=aux.y+dy[k];
			if(!viz[poz.x][poz.y] && mat[poz.x][poz.y]==0 && dist[poz.x][poz.y]>=D)
			{
				viz[poz.x][poz.y]=true;
				Q.push(poz);
			}
		}
	}
	return false;
}

inline void Cautare_Binara()
{
	int st,dr,mij;
	st=0;
	dr=n*m;
	while(st<=dr)
	{
		mij=(st+dr)/2;
		if(Posibil(mij)==true)
		{
			sol=max(sol,mij);
			st=mij+1;
		}
		else
			dr=mij-1;
	}
}

inline void Afisare()
{
	ofstream fout("barbar.out");
	fout<<sol<<"\n";
	fout.close();
}

int main()
{
	Citire();
	Calculare_Distante_Dragoni();
	Cautare_Binara();
	Afisare();
	return 0;
}