Pagini recente » Istoria paginii utilizator/acg_111000 | Monitorul de evaluare | Cod sursa (job #3234089) | Rating Renata (Renata) | Cod sursa (job #1053885)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("triangulare.in");
ofstream fout("triangulare.out");
const double EPS = 1e-10;
inline double abs(double X) {
if (X + EPS < 0)
return -X;
if (X - EPS > 0)
return X;
return 0;
}
inline bool egal(double A,double B) {
return abs(A - B) < EPS;
}
struct Punct {
double x, y;
Punct() { x = y = 0; }
Punct(const Punct &that) { *this = that; }
Punct(const double &a, const double &b) { x = a; y = b; }
bool operator==(const Punct &that) const {
return egal(x, that.x) && egal(y, that.y);
}
};
struct Segment {
Punct x, y;
double A, B, C;
Segment() { A = B = C = 0; }
Segment(const Segment &that) { *this = that; }
Segment(const Punct &a, const Punct &b) {
x = a; y = b;
A = b.y - a.y;
B = a.x - b.x;
C = A * a.x + B * a.y;
}
};
vector <pair <int, int> > ret;
vector <Punct> pct;
int T, N;
inline int sgn(double X) {
if (X + EPS < 0)
return -1;
if (X - EPS > 0)
return 1;
return 0;
}
inline int parte(Segment S, Punct P) {
return sgn(S.A * P.x + S.B * P.y - S.C);
}
inline bool intersectDreapta(Segment D, Segment S) {
return parte(D, S.x) * parte(D, S.y) <= 0;
}
inline bool apartineDreapta(Segment S, Punct P) {
return egal(S.A * P.x + S.B * P.y - S.C, 0);
}
inline bool apartine(Segment S, Punct P) {
return apartineDreapta(S, P) && egal(abs(S.x.x - P.x) + abs(S.y.x - P.x), abs(S.x.x - S.y.x)) && egal(abs(S.x.y - P.y) + abs(S.y.y - P.y), abs(S.x.y - S.y.y));
}
inline bool intersect(Segment S1, Segment S2) {
if (apartineDreapta(S1, S2.x) && apartineDreapta(S1, S2.y))
return apartine(S1, S2.x) || apartine(S1, S2.y) || apartine(S2, S1.x) || apartine(S2, S1.y);
return intersectDreapta(S1, S2) && intersectDreapta(S2, S1);
}
vector <pair <int, int> > solve(int N, vector<Punct> pct) {
vector <pair <int, int> > ret;
vector <Segment> seg;
for (int i = 0; i < N; ++ i)
seg.push_back(Segment(pct[i], pct[(i + 1) % N]));
for (int it = 0; it < N - 3; ++ it) {
int notFound = 1;
for (int i = 0; i < N && notFound; ++ i)
for (int j = i + 1; j < N && notFound; ++ j) {
if (i == (j + 1) % N || j == (i + 1) % N)
continue ;
int isOk = 1;
Segment check = Segment(pct[i], pct[j]);
for (int k = 0; k < (int)seg.size(); ++k) {
if ((seg[k].x == check.x && seg[k].y == check.y) || (seg[k].x == check.y && seg[k].y == check.x)) {
isOk = 0;
break ;
}
if (seg[k].x == check.x || seg[k].x == check.y || seg[k].y == check.x || seg[k].y == check.y)
continue ;
if (intersect(check, seg[k])) {
isOk = 0;
break ;
}
}
if (isOk) {
int inPoly = false;
Segment test = Segment(Punct(666013.555, -123456.789), Punct((pct[i].x + pct[j].x) / 2.0, (pct[i].y + pct[j].y) / 2.0));
for (int k = 0; k < N; ++ k)
if (intersect(test, seg[k]))
inPoly ^= 1;
if (!inPoly)
continue ;
ret.push_back(make_pair(i, j));
seg.push_back(check);
notFound = 0;
}
}
}
return ret;
}
int main () {
fin >> T;
for (int t = 1; t <= T; ++ t) {
fin >> N;
pct.clear();
for (int i = 0; i < N; ++ i) {
int x, y; fin >> x >> y;
pct.push_back(Punct(x, y));
}
ret = solve(N, pct);
for (int i = 0; i < N - 3; ++ i)
fout << ret[i].first << " " << ret[i].second << "\n";
}
}