Cod sursa(job #2326989)

Utilizator ChrisNeaguChris Neagu ChrisNeagu Data 24 ianuarie 2019 12:18:44
Problema Barbar Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.96 kb


#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <deque>
#include <set>
#include <stack>
//#include "graph.h"


using namespace std;

/*
double mysqrt(double x)
{
	if (x <= 0)
		return 0;       // if negative number throw an exception?
	int exp = 0;
	x = frexp(x, &exp); // extract binary exponent from x
	if (exp & 1) {      // we want exponent to be even
		exp--;
		x *= 2;
	}
	double y = (1 + x) / 2; // first approximation
	double z = 0;
	while (y != z) {    // yes, we CAN compare doubles here!
		z = y;
		y = (y + x / y) / 2;
	}
	return ldexp(y, exp / 2); // multiply answer by 2^(exp/2)
}*/

/*
void testaregraph()
{
	
	Node* nB = new Node('B');
	Node* nC = new Node('C');
	Node* nD = new Node('D');
	Node* nG = new Node('G');
	Node* nH = new Node('H');
	Node* nF = new Node('F');
	Node* nE = new Node('E');
	Node* nS = new Node('S');
	Node* nA = new Node('A');

	nB->AddLink(nA);
	nC->AddLink(nD); nC->AddLink(nE); nC->AddLink(nF); nC->AddLink(nS);
	nG->AddLink(nS); nG->AddLink(nF); nG->AddLink(nH);
	nH->AddLink(nE);
	nS->AddLink(nA);

	Graph gr(nA);
	gr.BreadthFirst();
	cout << endl;

	gr.Reset();
	gr.DepthFirst(gr._start);
	cout << endl;


	delete nB;
	delete nC;
	delete nD;
	delete nG;
	delete nH;
	delete nF;
	delete nE;
	delete nS;
	delete nA;
	}
	*/



struct sq
{
	//sq();
	//sq(char type) : _type(type) {}
	double _dmin;
	bool _visited=false;
	char _type;
};
struct stiva
{
	int _i, _j, _dir;
};
struct dragon : sq
{
	int _i, _j;
	dragon(sq const& a, int i, int j) : sq(a), _i(i), _j(j) {}
	
};

sq matrix[1001][1001];
stiva st[1000];
int sttop = 0;
int R, C;
stiva in;
stiva out;
ifstream fin("barbar.in");
ofstream fout("barbar.out");

bool checkposition(stiva const& c, double dd)
{
	int ii, jj;
	switch (c._dir)
	{
	case 1: // Nord
		ii = c._i - 1;
		jj = c._j;
		if (ii <= 0) return false;
		break;
		
	case 2: // Est
		ii = c._i;
		jj = c._j+1;
		if (jj >C)	return false;
		break;

	case 3: // Sud
		ii = c._i +1;
		jj = c._j;
		if (ii> R) return false;
		break;

	case 4: // Vest
		ii = c._i;
		jj = c._j-1;
		if (jj<=0) return false;
		break;
	default:
		return false;
		break;
	}
	if (matrix[ii][jj]._dmin < dd|| matrix[ii][jj]._type == 'D' || matrix[ii][jj]._type == '*')
	{
		return false;
	}
	// Verifica ca pozitia sa nu fie deja in stiva
	for (int i = 0; i < sttop; i++)
	{
		if (st[i]._i == ii && st[i]._j == jj)
		{
			return false;
		}
	}
	sttop++;
	st[sttop]._i = ii;
	st[sttop]._j = jj;
	st[sttop]._dir = 0;
	return true;
}

bool checkdistance(double dd)
{
	if (matrix[in._i][in._j]._dmin < dd)
	{
		return false;
	}
	sttop = 0;
	st[sttop] = in;
	while (sttop >= 0)
	{
		stiva* c = &st[sttop];
		bool success = false;
		while (c->_dir < 4)
		{
			c->_dir++;
			if (checkposition(*c, dd))
			{
				success = true;
				break;
			}
		}
		if (success)
		{
			if (st[sttop]._i == out._i&&st[sttop]._j == out._j)
			{
				return true;
			}
		}
		else
		{
			sttop--;
		}
	}
	return false;
}

int main()
{
	fin >> R >> C;
	vector<dragon> dragoni;
	set<double> distante;
	
	for (int i = 1; i <= R; i++)
		for (int j = 1; j <= C; j++)
		{
			fin >> matrix[i][j]._type;
			if (matrix[i][j]._type == 'D')
			{
				dragoni.push_back(dragon(matrix[i][j], i, j));
			}
			if (matrix[i][j]._type == 'I')
			{
				in._i = i;
				in._j = j;
				in._dir = 0;
			}
			if (matrix[i][j]._type == 'O')
			{
				out._i = i;
				out._j = j;
				out._dir= 0;
			}
		}
	fin.close();
	for (int i = 1; i <= R; i++)
		for (int j = 1; j <= C; j++)
			if (matrix[i][j]._type == '.'  || matrix[i][j]._type == 'I' || matrix[i][j]._type == 'O')
			{
				double dist, tempi, tempj, dmin = R*C;
				for (int z = 0; z < dragoni.size(); z++)
				{
					tempj = fabs(j - dragoni[z]._j);
					tempi = fabs(i - dragoni[z]._i);
					//dist = sqrt(tempi*tempi + tempj * tempj);
					dist = tempi + tempj;
					if (dist < dmin)
					{
						dmin = dist;
					}
				}
				distante.insert(dmin);
				matrix[i][j]._dmin = dmin;
			}
	vector<double> vdist(distante.begin(),distante.end()) ;
	int ix;
	for (ix = 0; ix < vdist.size(); ix++)
	{
		bool res = checkdistance(vdist[ix]);
		if (!res)
			break;
	}
	if (ix == 0)
	{
		fout << -1; ; //nu exista solutie
	}
	else
	{
		fout << vdist[ix - 1];
	}
	system("pause");
	return 0;
}


//void main()
//{
//	
//
//
//
//		/*int x;
//		cin >> x;
//		cout << mysqrt(x);*/
//
//
//		//testaregraph();
//	
//
//	system("pause");
//}
//
////
//#include <iostream>
//#include <fstream>
//
//using namespace std;
//
//unsigned long a, b;
//
//ifstream fin("cmmdc.in");
//ofstream fout("cmmdc.out");
//
//int main()
//{
//	fin >> a >> b;
//	fin.close();
//	while (a != b)
//	{
//		if (a>b)
//			a = a - b;
//		else
//			b = b - a;
//	}
//	(a==1) ? fout << 0 : fout << a;
//	fout.close();
//	return 0;
//}