C Operation Love(2020牛客暑期多校训练营(第三场))(计算几何)

传送门
img
img
题目大意:顺时针或逆时针输入手掌上的20个坐标,判断是左手掌还是右手掌。数据范围[-1000.000,1000.000]

题解:发现大拇指、小拇指和最底下的边的长度是唯一的,根据长度唯一找到大拇指上面和下面的点以及小拇指下面的点。运用叉积判断线段的走向,因为大拇指永远在底下那条边的右边。
叉积

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps=1e-2;
int T;

double X[20],Y[20];

struct Point
{
	double x,y;
}p[4];

double dis(int a,int b)
{
	return (X[a]-X[b])*(X[a]-X[b])+(Y[a]-Y[b])*(Y[a]-Y[b]);
} 

void Find_Point()
{
	for(int i=0;i<20;i++)
	{
		int pre=(i-1+20)%20;
		int suf=(i+1)%20;
		if(fabs(dis(i,pre)-1.0)<=eps&&fabs(dis(i,suf)-36.0)<=eps) p[1].x=X[i],p[1].y=Y[i];
		if(fabs(dis(i,suf)-1.0)<=eps&&fabs(dis(i,pre)-36.0)<=eps) p[1].x=X[i],p[1].y=Y[i];
		if(fabs(dis(i,pre)-36.0)<=eps&&fabs(dis(i,suf)-81.0)<=eps) p[2].x=X[i],p[2].y=Y[i];
		if(fabs(dis(i,suf)-36.0)<=eps&&fabs(dis(i,pre)-81.0)<=eps) p[2].x=X[i],p[2].y=Y[i];
		if(fabs(dis(i,pre)-81.0)<=eps&&fabs(dis(i,suf)-64.0)<=eps) p[3].x=X[i],p[3].y=Y[i];
		if(fabs(dis(i,suf)-81.0)<=eps&&fabs(dis(i,pre)-64.0)<=eps) p[3].x=X[i],p[3].y=Y[i];
	}	
}

void slove_Chaji()
{
	Point ca,ba;
	ca.x=p[1].x-p[3].x;ca.y=p[1].y-p[3].y;
	ba.x=p[2].x-p[3].x;ba.y=p[2].y-p[3].y;
	int p;
	p=ca.x*ba.y-ba.x*ca.y;
	if(p>0) cout<<"right\n";
	else cout<<"left\n"; 
}

int main()
{
	cin>>T;
	while(T--)
	{
		for(int i=0;i<20;i++)
		{
			cin>>X[i]>>Y[i];
		}
		Find_Point();
		slove_Chaji();
	} 
	return 0;
}

posted @ 2020-07-25 00:17  ANhour  阅读(200)  评论(0编辑  收藏  举报