题意:给定
思路:
对于
通过多次画图可以发现,我们可以按照横坐标或纵坐标排序甚至极角进行排序。
随后相邻最近的两个点相连成一个线段,这样一定不存在两个相交的线段。
而且每一个合法的线段最多只需要一次操作便可得到,即总操作数不超过
故不存在无法完成输出
此题得解。
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int A = 1e5 + 10;
class P{
public:
int x,y,id;
bool operator<(const P& rhs)const{
if(x != rhs.x) return x < rhs.x;
return y < rhs.y;
}
}a[A<<2];
int con[A<<2],pos[A<<2];
vector<pair<int,int> > vec;
int main(){
int T;scanf("%d",&T);
while(T--){
int n;scanf("%d",&n);
for(int i=1 ;i<=2*n ;i++){
a[i].id = i;
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=1 ;i<=n ;i++){
int u,v;
scanf("%d%d",&u,&v);
con[u] = v;con[v] = u;
}
sort(a+1,a+1+2*n);
vec.clear();
for(int i=1 ;i<=2*n ;i++){
pos[a[i].id] = i;
}
for(int i=1 ;i<=2*n; i+=2){
int u = a[i].id,v = a[i+1].id;
if(con[u] == v) continue;
int tem = con[u];
vec.push_back(make_pair(tem,v));
a[pos[tem]].id = v;
swap(pos[tem],pos[v]);
}
int Siz = vec.size();
printf("%d\n",Siz);
for(int i=0 ;i<Siz ;i++){
printf("%d %d\n",vec[i].first,vec[i].second);
}
}
return 0;
}