Cod sursa(job #1056913)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 14 decembrie 2013 13:53:19
Problema Triangulare Scor 0
Compilator cpp Status done
Runda ONIS 2014, Runda 1 Marime 3 kb
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#define pii pair<int, int>
using namespace std;
int T, n, N, poz[60];
struct Punct{int x, y, ind;};
Punct P[60];
vector <pii> sol;
bool eliminat[60];

inline long long Modul(long long x)
{
	if(x < 0LL)
		return (-x);
	return x;
}

inline long long Arie(Punct A, Punct B, Punct C)
{
	return (1LL * A.x * B.y + 1LL * B.x * C.y + 1LL * C.x * A.y - 1LL * C.x * B.y - 1LL * B.x * A.y - 1LL * A.x * C.y);
}

inline void Elimina()
{
	int I, i, j, k;
	long long S, S1, S2, S3;
	bool ok, st, dr;
	for(i = 2; i <= N + 1; ++i)
		poz[P[i].ind] = i;
	P[0] = P[N];
	P[1] = P[N + 1];
	P[N + 2] = P[2];
	P[N + 3] = P[3];
	for(I = 0; I < n; ++I)
	{
		if(eliminat[I])
			continue;
		i = poz[I];
		ok = true;
		st = dr = false;
		for(j = 2; j <= N + 1; ++j)
		{
			S = Arie(P[i - 2], P[i], P[j]);
			if(S < 0LL)
				st = true;
			if(S > 0LL)
				dr = true;
		}
		if(!(st && dr))
			ok = false;
		for(j = 2; j <= N + 1 && ok; ++j)
		{
			if(P[j].ind == P[i].ind || P[j].ind == P[i - 1].ind || P[j].ind == P[i - 2].ind)
				continue;
			S = Modul(Arie(P[i - 2], P[i - 1], P[i]));
			S1 = Modul(Arie(P[j], P[i - 1], P[i]));
			S2 = Modul(Arie(P[i - 2], P[j], P[i]));
			S3 = Modul(Arie(P[i - 2], P[i - 1], P[j]));
			if(S == S1 + S2 + S3)
				ok = false;
		}
		if(ok)
		{
			sol.push_back(make_pair(min(P[i].ind, P[i - 2].ind), max(P[i].ind, P[i - 2].ind)));
			j = i - 1;
			eliminat[P[i - 1].ind] = true;
			if(j < 2 || j > N + 1)
				j = poz[P[i - 1].ind];
			for(k = j + 1; k <= N + 1; ++k)
				P[k - 1] = P[k];
			N--;
			break;
		}
		else
		{
			ok = true;
			st = dr = false;
			for(j = 2; j <= N + 1; ++j)
			{
				S = Arie(P[i + 2], P[i], P[j]);
				if(S < 0LL)
					st = true;
				if(S > 0LL)
					dr = true;
			}
			if(!(st && dr))
				ok = false;
			for(j = 2; j <= N + 1 && ok; ++j)
			{
				if(P[j].ind == P[i].ind || P[j].ind == P[i + 1].ind || P[j].ind == P[i + 2].ind)
					continue;
				S = Modul(Arie(P[i + 2], P[i + 1], P[i]));
				S1 = Modul(Arie(P[j], P[i + 1], P[i]));
				S2 = Modul(Arie(P[i + 2], P[j], P[i]));
				S3 = Modul(Arie(P[i + 2], P[i + 1], P[j]));
				if(S == S1 + S2 + S3)
					ok = false;
			}
			if(ok)
			{
				sol.push_back(make_pair(min(P[i].ind, P[i + 2].ind), max(P[i].ind, P[i + 2].ind)));
				j = i + 1;
				eliminat[P[i + 1].ind] = true;
				if(j < 2 || j > N + 1)
					j = poz[P[i + 1].ind];
				for(k = j + 1; k <= N + 1; ++k)
					P[k - 1] = P[k];
				N--;
				break;
			}
		}
	}
}

int main()
{
	int i;
	ifstream fin("triangulare.in");
	ofstream fout("triangulare.out");
	fin >> T;
	while(T--)
	{
		fin >> n;
		N = n;
		for(i = 2; i <= n + 1; ++i)
		{
			fin >> P[i].x >> P[i].y;
			P[i].ind = i - 2;
		}
		for(i = 0; i < n - 3; ++i)
			Elimina();
		sort(sol.begin(), sol.end());
		for(i = 0 ; i < n - 3; ++i)
			fout << sol[i].first << ' ' << sol[i].second << "\n";
		sol.clear();
	}
	fin.close();
	fout.close();
	return 0;
}