版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
题目
CF
在三维空间内给你
个点坐标
,保证
为偶数,每次可以配对两个点然后删去这两个点
,但要满足以他们为顶点构成的空间内没有点(包括边界),即没有点
满足
,输出
对方案?
思路
非常巧妙,时间复杂度为
其中
为空间维数
我们考虑一维时候方案非常显然,挨着配对即可,…注意此时
为奇数时可以留下来任意一个点此时固定
考虑而为时候方案,我们可以对每一条线
上的点做一维操作,然后就保证剩下点的
互不相等,又用类似方法即可
更高维度以此类推。
于是我们先固定两维
然后配对,然后固定一维
再配对,最后剩下的点再配对即可
体现为多个sort…
代码
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int read(){
bool f=0;int x=0;char c=getchar();
while(c<'0'||'9'<c){if(c=='-')f=1;c=getchar();}
while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return !f?x:-x;
}
#define MAXN 500000
#define INF 0x3f3f3f3f
struct node{
int x,y,z,id,f;
friend bool operator < (node a,node b){return (a.f==b.f?(a.x==b.x?(a.y==b.y?a.z<b.z:a.y<b.y):a.x<b.x):a.f<b.f);}
}a[MAXN+5];
int main(){
int n=read();
for(int i=1;i<=n;i++){
int x=read(),y=read(),z=read();
a[i]=(node){x,y,z,i,0};
}
sort(a+1,a+n+1);
for(int i=1;i<n;i++)
if(!a[i].f&&!a[i+1].f&&a[i].x==a[i+1].x&&a[i].y==a[i+1].y){
printf("%d %d\n",a[i].id,a[i+1].id);
a[i].f=1,a[i+1].f=1;
}
sort(a+1,a+n+1);
for(int i=1;i<n;i++)
if(!a[i].f&&!a[i+1].f&&a[i].x==a[i+1].x){
printf("%d %d\n",a[i].id,a[i+1].id);
a[i].f=1,a[i+1].f=1;
}
sort(a+1,a+n+1);
for(int i=1;i<n;i++)
if(!a[i].f&&!a[i+1].f){
printf("%d %d\n",a[i].id,a[i+1].id);
a[i].f=1,a[i+1].f=1;
}
return 0;
}
思考
以后遇到多维度问题可以想想最简单一维或者两维怎么做,或者理解为固定 维,只研究剩下的一个维度进行思考