[Acm] hdu 5206:Four Inages Strategy(计算几何)

Four Inages Strategy

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 822 Accepted Submission(s): 327

Problem Description
Young F found a secret record which inherited from ancient times in ancestral home by accident, which named "Four Inages Strategy". He couldn't restrain inner exciting, open the record, and read it carefully. " Place four magic stones at four points as array element in space, if four magic stones form a square, then strategy activates, destroying enemy around". Young F traveled to all corners of the country, and have collected four magic stones finally. He placed four magic stones at four points, but didn't know whether strategy could active successfully. So, could you help him?

Input
Multiple test cases, the first line contains an integer T(no more than 10000), indicating the number of cases. Each test case contains twelve integers x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,|x|,|y|,|z|≤100000,representing coordinate of four points. Any pair of points are distinct.

Output
For each case, the output should occupies exactly one line. The output format is Case #x: ans, here x is the data number begins at 1, if your answer is yes,ans is Yes, otherwise ans is No.

Sample Input
2
0 0 0 0 1 0 1 0 0 1 1 0
1 1 1 2 2 2 3 3 3 4 4 4

Sample Output
Case #1: Yes
Case #2: No

Source
BestCoder Round #38 ($)

Recommend
hujie | We have carefully selected several similar problems for you: 5213 5212 5211 5210 5209


题意
先输入一个整型数 T,表示有T组测试数据。
每组测试数据有12个整型数,分别是4个点的三维坐标(x,y,z)。
判断这四个点是否构成一个正方形。

思路
判断空间上4个点是否形成一个正方形方法有很多,这里给出一种方法,在p2,p3,p4中枚举两个点作为p1的邻点,不妨设为pi,pj,然后判断p1pi与p1pj是否相等、互相垂直,然后由向量法,最后一个点坐标应该为pi+pj−p1,判断是否相等就好了。
另外,由于点都是整点,所以很多奇奇怪怪的方法是找不到数据hack的,如果以后碰到以浮点数读入的可要小心咯。

代码

#include 
#include 
using namespace std;
struct Point3{
    long long x,y,z;
};
long long dist(Point3 p1,Point3 p2)
{
    return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z);
}

//矢量差 U - V
Point3 subt(Point3 u,Point3 v){
    Point3 ret;
    ret.x=u.x-v.x;
    ret.y=u.y-v.y;
    ret.z=u.z-v.z;
    return ret;
}
//计算dot product U . V
double dmult(Point3 u,Point3 v){
    return u.x*v.x+u.y*v.y+u.z*v.z;
}

int perpendicular(Point3 u1,Point3 u2,Point3 v1,Point3 v2){
    return dmult(subt(u1,u2),subt(v1,v2))==0;
}

int main()
{
    int T,Case,i,j,k;
    scanf("%d",&T);
    for(Case=1;Case<=T;Case++){
        Point3 p[4];
        bool f = false;
        scanf("%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld",&p[0].x,&p[0].y,&p[0].z,&p[1].x,&p[1].y,&p[1].z,&p[2].x,&p[2].y,&p[2].z,&p[3].x,&p[3].y,&p[3].z);
        for(i=1;i<4;i++){
            for(j=i+1;j<4;j++){
                //找到第三个点
                for(k=1;k<4;k++)
                    if(k!=i && k!=j)
                        break;
                //判断p0pi和p0pj是否相等且垂直 且p0pi^2 + p0pj^2 == p0pk^2
                if(dist(p[0],p[i])==dist(p[0],p[j]) && perpendicular(p[0],p[i],p[0],p[j]) && dist(p[0],p[i])+dist(p[0],p[j])==dist(p[0],p[k]) ){
                    f = true;
                    goto label;
                }
            }
        }
        label:
        if(f)
            printf("Case #%d: Yes\n",Case);
        else
            printf("Case #%d: No\n",Case);
    }
    return 0;
}

你可能感兴趣的:(算法,acm)