题目链接:https://ac.nowcoder.com/acm/contest/5668/C
简要题意:
下图为某机器人右手手印的形状,左手为右手的对称图形,现在给你一个机器人的手印(可能经过平移和旋转),请判断是左手还是右手(保证一定是其中一只手)
给你20个点,按照顺时针方向或者逆时针方向给出,如下图(该图为右掌)
图片说明
解题思路:
计算几何顺/逆时钟判断,(与给出三角形三个顶点求面积就差个绝对值),判断出给的点是按照顺/逆时针方向给的就可以通过边来判断左手还是右手了。
代码实现上这道题eps需要给大点,不需要那么精确。
证明:
https://www.zybang.com/question/761f8b42a12a5b3947f165e685fd89fd.html
总结出来的计算技巧(交叉相乘,注意正负号):
图片说明

代码:

#include<bits/stdc++.h>
using namespace std;
#define eps 1e-1
struct point{
    double x, y;
}s[30];

double dis(point a, point b)
{
    return 1.0 * sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double axb(point A, point B, point C)
{
    return A.x*B.y-B.x*A.y+B.x*C.y-C.x*B.y+C.x*A.y-A.x*C.y;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        for(int i = 1; i <= 20; i++) {
            scanf("%lf%lf",&s[i].x,&s[i].y);
            s[i + 20] = s[i];    //一圈 
        }    
        int q1, q2, q3;
        for(int i = 1; i <= 20; i++) {
            if(fabs(dis(s[i], s[i+1]) - 9.0) < eps)
            {
                q1 = i;
                q2 = i + 1;
                q3 = i + 2;
                break;
            }
        }
        bool flag; // 左1右0 
        if(axb(s[q1],s[q2],s[q3]) < 0.0)    //顺时针 
        {
            for(int i = 1; i <= 20; i++)
            {
                double dis1 = dis(s[i],s[i+1]);
                if(fabs(dis1 - 9.0) < eps)
                {
                    double dis2 = dis(s[i+1], s[i+2]);
                    if(fabs(dis2 - 8.0) < eps)
                        flag =  1;
                    else
                        flag = 0;
                    break;
                }
            }
        }
        else     //逆时针 
        {
            for(int i = 1; i <= 20; i++)
            {
                double dis1 = dis(s[i],s[i+1]);
                if(fabs(dis1 - 9.0) < eps)
                {
                    double dis2 = dis(s[i+1], s[i+2]);
                    if(fabs(dis2 - 8.0) < eps)
                        flag =  0;
                    else
                        flag = 1;
                    break;
                }
            }
        }
        if(flag) {
            printf("left\n");
        }
        else {
            printf("right\n");
        }
     }
}