题意:
给你8个点的坐标,坐标的x、y、z值没有顺序,问你是否有某种方法使这8个点构成一个立方体(立方体是正方体,Orz........刚开始不知道想了好久)。
思路:
暴力枚举每个坐标的次序,然后对于每种状况去判断下是否能构成正方体,判断方法是算出每个点和其他点的距离,这样有7条边,判断下最小的3条是否一样,中间的3条是否一样,最小的边长*2是否等于中间的边长,最小的边长*3是否等于最长的边长(这里自己画个图比较好理解),这样时间复杂度为6^8*64。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef __int64 LL;
LL p[10][5];
int order[10][5];
bool ok(){
LL dis[35];
for(int i=1;i<=8;i++){
int cnt=0;
for(int j=1;j<=8;j++){
if(i==j) continue;
dis[cnt]=0;
dis[cnt]+=(p[i][order[i][0]]-p[j][order[j][0]])*(p[i][order[i][0]]-p[j][order[j][0]]);
dis[cnt]+=(p[i][order[i][1]]-p[j][order[j][1]])*(p[i][order[i][1]]-p[j][order[j][1]]);
dis[cnt]+=(p[i][order[i][2]]-p[j][order[j][2]])*(p[i][order[i][2]]-p[j][order[j][2]]);
cnt++;
}
sort(dis,dis+cnt);
if(dis[0]==0) return false;
if(dis[0]!=dis[1]||dis[0]!=dis[2]||dis[1]!=dis[2]) return false;
if(dis[3]!=dis[4]||dis[3]!=dis[5]||dis[4]!=dis[5]) return false;
if(dis[0]*2!=dis[3]||dis[0]*3!=dis[6]) return false;
}
return true;
}
int main(){
for(int i=1;i<=8;i++){
for(int j=0;j<3;j++){
scanf("%I64d",&p[i][j]);
order[i][j]=j;
}
}
bool flag=false;
do{
do{
do{
do{
do{
do{
do{
do{
if(ok()){
flag=true;
break;
}
}while(next_permutation(order[1],order[1]+3));
if(flag) break;
}while(next_permutation(order[2],order[2]+3));
if(flag) break;
}while(next_permutation(order[3],order[3]+3));
if(flag) break;
}while(next_permutation(order[4],order[4]+3));
if(flag) break;
}while(next_permutation(order[5],order[5]+3));
if(flag) break;
}while(next_permutation(order[6],order[6]+3));
if(flag) break;
}while(next_permutation(order[7],order[7]+3));
if(flag) break;
}while(next_permutation(order[8],order[8]+3));
if(flag){
printf("YES\n");
for(int i=1;i<=8;i++){
printf("%I64d %I64d %I64d\n",p[i][order[i][0]],p[i][order[i][1]],p[i][order[i][2]]);
}
}
else printf("NO\n");
return 0;
}