题目链接
题意:三维空间中有偶数个点,每次你可以选择两个点将其删除,但是需要保证以两点为端点的长方体不能包含未删除的点。问怎样可以将所有点删除。
题解:对x,y,z排序,先x, y相同的点删掉,再x相同的删掉,再把剩下的点删掉。这样保证每次删除的点对中间不会存在别的点。对于c2,因为n比较大,所以我用了并查集维护每个位置后第一个为空的位置。
c1:
#include<bits/stdc++.h>
using namespace std;
const int N = 3100;
int vis[N];
struct node{
int x, y, z, id;
bool friend operator < (node a, node b){
if(a.x != b.x) return a.x > b.x;
if(a.y != b.y) return a.y > b.y;
return a.z > b.z;
}
}a[N];
vector<int>ans[N];
int main()
{
int n, cnt = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z), a[i].id = i;
sort(a + 1, a + 1 + n);
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
if(a[i].x == a[i + 1].x && a[i].y == a[i + 1].y){
vis[i] = vis[i + 1] = 1;
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[i + 1].id);
}
}
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
for(int j = i + 1; j <= n; ++j)
if(!vis[j]){
if(a[i].x == a[j].x){
vis[i] = vis[j] = 1;
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[j].id);
}
break;
}
}
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
for(int j = i + 1; j <= n; ++j)
if(!vis[j]){
vis[i] = vis[j] = 1;
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[j].id);
break;
}
}
for(int i = 1; i <= cnt; ++i){
for(auto t : ans[i]) printf("%d ", t);
puts("");
}
}
c2:
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 100;
int vis[N], pre[N];
struct node{
int x, y, z, id;
bool friend operator < (node a, node b){
if(a.x != b.x) return a.x > b.x;
if(a.y != b.y) return a.y > b.y;
return a.z > b.z;
}
}a[N];
vector<int>ans[N];
inline void find(int &x){
while(x!=pre[x])
x=pre[x]=pre[pre[x]];
}
int main()
{
int n, cnt = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
pre[i] = i;
for(int i = 1; i <= n; ++i)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z), a[i].id = i;
sort(a + 1, a + 1 + n);
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
if(a[i].x == a[i + 1].x && a[i].y == a[i + 1].y){
pre[i] = i + 2;
pre[i + 1] = i + 2;
vis[i] = vis[i + 1] = 1;
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[i + 1].id);
}
}
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
int t1 = i;
find(t1);
if(t1 == i) {
t1 += 1;
find(t1);
}
if(a[i].x == a[t1].x){
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[t1].id);
vis[i] = vis[t1] = 1;
int t2 = (t1 + 1);
find(t2);
pre[i] = t2;
pre[t1] = t2;
}
}
for(int i = 1; i < n; ++i){
if(vis[i]) continue;
int t1 = i;
find(t1);
if(t1 == i) {
t1 += 1;
find(t1);
}
++cnt;
ans[cnt].push_back(a[i].id);
ans[cnt].push_back(a[t1].id);
vis[i] = vis[t1] = 1;
int t2 = (t1 + 1);
find(t2);
pre[i] = t2;
pre[t1] = t2;
}
for(int i = 1; i <= cnt; ++i){
for(auto t : ans[i]) printf("%d ", t);
puts("");
}
}