Cod sursa(job #1009637)

Utilizator ScoobyDoo38Nita Adrian Valentin ScoobyDoo38 Data 13 octombrie 2013 16:40:19
Problema Barbar Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.05 kb
#include <fstream>
#include <vector>
#include <utility>
#include <queue>

using namespace std;

#define elif else if
class Problem
{
private:
	int r, c;
	vector< vector< unsigned > > grid;
	vector< vector< bool > > bob;
	pair< int, int > barbar;

	int answer;

	static const unsigned empty = 9913;
	static const unsigned bad = 13;
	unsigned dragon;
	static const unsigned start = empty + 1;
	static const unsigned finish = empty - 1;

public:
	Problem( string input )
	{
		ifstream in( input );

		in >> r >> c;

		char buff;

		dragon = 1113;
		
		grid.resize( r );
		bob.resize( r );
		for ( int i = 0; i < r; i++ )
		{
			grid[ i ].resize( c );
			bob[ i ].resize( c );
			for ( int j = 0; j < c; j++ )
			{
				in >> buff;

				if ( buff == '.' )
				{
					grid[ i ][ j ] = empty;
				}
				elif ( buff == '*' )
				{
					grid[ i ][ j ] = bad;
				}
				elif ( buff == 'D' )
				{
					grid[ i ][ j ] = dragon;
				}
				elif ( buff == 'I' )
				{
					grid[ i ][ j ] = start;
					barbar.first = i;
					barbar.second = j;
				}
				else
				{
					grid[ i ][ j ] = finish;
				}
			}
		}

		in.close();

		solve();
	}

private:
	void solve()
	{
		answer = 0;

		while ( bfs() )
		{
			answer++;

			for ( int i = 0; i < r; i++ )
			{
				for ( int j = 0; j < c; j++ )
				{
					if ( grid[ i ][ j ] == dragon )
					{
						if ( i > 0 && grid[ i - 1 ][ j ] != finish && grid[ i - 1 ][ j ] != start )
						{
							grid[ i - 1 ][ j ] = dragon + 1;
						}
						elif ( i > 0 && ( grid[ i - 1 ][ j ] == finish || grid[ i - 1 ][ j ] == start ) )
						{
							break;
						}
						if ( i < r - 1 && grid[ i + 1 ][ j ] != finish && grid[ i + 1 ][ j ] != start )
						{
							grid[ i + 1 ][ j ] = dragon + 1;
						}
						elif ( i < r - 1 && ( grid[ i + 1 ][ j ] == finish || grid[ i + 1 ][ j ] == start ) )
						{
							break;
						}
						if ( j > 0 && grid[ i ][ j - 1 ] != finish && grid[ i ][ j - 1 ] != start )
						{
							grid[ i ][ j - 1 ] = dragon + 1;
						}
						elif ( j > 0 && ( grid[ i ][ j - 1 ] == finish || grid[ i ][ j - 1 ] == start ) )
						{
							break;
						}
						if ( j < c - 1 && grid[ i ][ j + 1 ] != finish && grid[ i ][ j + 1 ] != start )
						{
							grid[ i ][ j + 1 ] = dragon + 1;
						}
						elif ( j < c - 1 && ( grid[ i ][ j + 1 ] == finish || grid[ i ][ j + 1 ] == start ) )
						{
							break;
						}
					}
				}
			}
			dragon++;
		}
	}

	bool bfs()
	{
		for ( int i = 0; i < r; i++ )
		{
			for ( int j = 0; j < c; j++ )
			{
				bob[ i ][ j ] = false;
			}
		}

		int x = barbar.first;
		int y = barbar.second;

		queue< pair< int, int > > qu;
		qu.push( make_pair( x, y ) );
		bob[ x ][ y ] = true;

		while ( !qu.empty() )
		{
			auto p = qu.front();
			qu.pop();

			x = p.first;
			y = p.second;

			if ( x > 0 && grid[ x - 1 ][ y ] == empty && !bob[ x - 1 ][ y ] )
			{
				qu.push( make_pair( x - 1, y ) );
				bob[ x - 1 ][ y ] = true;
			}
			elif ( x > 0 && grid[ x - 1 ][ y ] == finish )
			{
				return true;
			}
			if ( x < r - 1 && grid[ x + 1 ][ y ] == empty && !bob[ x + 1 ][ y ] )
			{
				qu.push( make_pair( x + 1, y ) );
				bob[ x + 1 ][ y ] = true;
			}
			elif ( x < r - 1 && grid[ x + 1 ][ y ] == finish )
			{
				return true;
			}
			if ( y > 0 && grid[ x ][ y - 1 ] == empty && !bob[ x ][ y - 1 ] )
			{
				qu.push( make_pair( x, y - 1 ) );
				bob[ x ][ y - 1 ] = true;
			}
			elif ( y > 0 && grid[ x ][ y - 1 ] == finish )
			{
				return true;
			}
			if ( y < c - 1 && grid[ x ][ y + 1 ] == empty && !bob[ x ][ y + 1 ] )
			{
				qu.push( make_pair( x, y + 1 ) );
				bob[ x ][ y + 1 ] = true;
			}
			elif ( y < c - 1 && grid[ x ][ y + 1 ] == finish )
			{
				return true;
			}
		}

		return false;
	}

public:
	void showResult( string output )
	{
		ofstream out( output );

		out << answer;

		out.close();
	}
};
#undef elif

int main()
{
	Problem* p = new Problem( "barbar.in" );
	p->showResult( "barbar.out" );
	
	return 0;
}