/** GOKURI */ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define FNAME "ant.txt" #define cin fin typedef complex icomp; inline int outer_prod( const icomp& a, const icomp& b ) { return a.real()*b.imag() - a.imag()*b.real(); } inline int inner_prod( const icomp& a, const icomp& b ) { return a.real()*b.real() + a.imag()*b.imag(); } inline bool LessY( const icomp& a, const icomp& b ) { if( a.imag() != b.imag() ) return a.imag() solve( const vector& vi ) { int m = min_element(vi.begin(), vi.end(), LessY ) - vi.begin(); vector vo; vo.push_back( vi[m] ); deque rest; for(int i=0; i!=vi.size(); ++i) if( i!=m ) rest.push_back( vi[i] ); icomp p( 1, 0 ); while( !rest.empty() ) { // take min_arg (thus, max_cos(arg)) int MinIdx = -1; icomp MinV; for(int i=0; i!=rest.size(); ++i) { icomp q = rest[i] - vo.back(); // 0<=arg(q/p)<180 const int op = outer_prod(p,q); const int ip = inner_prod(p,q); const int normQ = norm(q); if( op<0 || op==0&&ip<0 ) continue; // && lex_order( arg(q/p), norm(q) ) is minimum bool update = false; if( MinIdx == -1 ) update = true; else if( outer_prod(q,MinV) > 0 ) update = true; else if( outer_prod(q,MinV)==0 && norm(q) < norm(MinV) ) update = true; if( update ) { MinIdx = i; MinV = q; } } vo.push_back( rest[MinIdx] ); rest.erase( rest.begin()+MinIdx ); p = vo[vo.size()-1] - vo[vo.size()-2]; } return vo; } int main() { ifstream fin(FNAME); if(!fin) return -1; int nCase; cin>>nCase; while(nCase--) { // input map rmap; vector pts; int nPt; cin>>nPt; while( nPt-- ) { int id, x, y; cin >> id >> x >> y; pts.push_back( icomp(x,y) ); icomp pt(x,y); rmap[pt] = id; } // solve vector result = solve(pts); // output cout << result.size(); for(int i=0; i!=result.size(); ++i) { if(!rmap.count(result[i])) abort(); cout << ' ' << rmap[result[i]]; } cout << endl; } return 0; }