2020牛客暑期多校训练营第三场C题Operation Love

Operation Love

传送门

题目大意:

爱丽丝是机器人社会的美人。 很多多机器人想嫁给她。 爱丽丝决定嫁给可以解决以下难题的机器人:
首先,爱丽丝右手掌的形状如下:
在这里插入图片描述
爱丽丝的左手掌形状与她的右手掌对称。
在这个难题中,爱丽丝将给挑战者她手掌的许多手印。 挑战者必须正确告诉Alice每个手印是她的左手掌还是右手掌。 请注意,爱丽丝手掌的手印由其2D平面坐标按顺时针或逆时针顺序给出。 并且形状可以旋转和平移。 但是形状不会被放大或缩小。
尽管您不是机器人,但您对解决难题很感兴趣。 请尝试解决这个难题。

输入:

第一行:一个整数t(1≤t≤10^3),表示Alice的手印数。
每个手印都由一个由20个点组成的简单多边形描述。
输入中的所有坐标值都在[-1000.0000000,1000.000000]范围内。

输出:

对于每个手掌的印迹,打印一行“right”或“left”,表示手印分别是右手掌或左手掌。

样例输入:
样例输入1:
2
1.000000 0.000000
10.000000 0.000000
10.000000 8.000000
9.000000 8.000000
9.000000 5.000000
8.000000 5.000000
8.000000 10.000000
7.000000 10.000000
7.000000 5.000000
6.000000 5.000000
6.000000 10.000000
5.000000 10.000000
5.000000 5.000000
4.000000 5.000000
4.000000 10.000000
3.000000 10.000000
3.000000 3.000000
2.000000 3.000000
2.000000 6.000000
1.000000 6.000000
-1.000123 0.000000
-10.000123 0.000000
-10.000123 8.000000
-9.000123 8.000000
-9.000123 5.000000
-8.000123 5.000000
-8.000123 10.000000
-7.000123 10.000000
-7.000123 5.000000
-6.000123 5.000000
-6.000123 10.000000
-5.000123 10.000000
-5.000123 5.000000
-4.000123 5.000000
-4.000123 10.000000
-3.000123 10.000000
-3.000123 3.000000
-2.000123 3.000000
-2.000123 6.000000
-1.000123 6.000000
样例输出1:
right
left
样例输入2:
1
19.471068 -6.709056
13.814214 -1.052201
13.107107 -1.759308
15.228427 -3.880629
14.521320 -4.587735
10.985786 -1.052201
10.278680 -1.759308
13.814214 -5.294842
13.107107 -6.001949
9.571573 -2.466415
8.864466 -3.173522
12.400000 -6.709056
11.692893 -7.416162
8.157359 -3.880629
7.450253 -4.587735
12.400000 -9.537483
11.692893 -10.244590
9.571573 -8.123269
8.864466 -8.830376
13.107107 -13.073017
样例输出2:
right
样例2解释:

在这里插入图片描述
显然是右手掌。

分析:

先找出长度为9的底边,再运用叉乘来判断方向
叉乘动画演示
用右手螺旋定则判断叉乘结果的方向
模板

代码:
#include<cmath>
#include<iostream>
using namespace std;
const double eps=0.1;
double x[25],y[25];
int T,root;
int sgn(double x)
{	
	if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    else return 1;
}
struct point{
	double x,y;
    point(){}point(double _x,double _y){x=_x;y=_y;}
    point operator -(const point &b)const{return point(x-b.x,y-b.y);}
    double operator ^(const point &b)const{return x*b.y-y*b.x;}
    double operator *(const point &b)const{return x*b.x+y*b.y;}
};
struct Line{
	point s,e;
    Line(){}
    Line(point _s,point _e){s=_s,e=_e;}
}l[5050];
bool check(point p)
{
    if(sgn((l[root].s-p)^(l[root].s-l[root].e))>0) return true;
    else return false;
}//叉乘判断方向
int main()
{
	scanf("%d",&T);
    while(T--)
	{
    	for(int i=0;i<20;i++)cin>>x[i]>>y[i];
        for(int i=0;i<20;i++)
            if( fabs( sqrt( ( x[i] - x[(i+19)%20] ) * ( x[i] - x[(i+19)%20]) + (y[i]-y[(i+19)%20] ) * ( y[i] - y[(i+19)%20] ) ) - 9 ) < = eps)
				root=i;//求出长度为9的底边的两个顶点为root和(root-1)%20
		point p1=point(x[(root+1)%20],y[(root+1)%20]);
		point p2=point(x[root],y[root]);
		point p3=point(x[(root+19)%20],y[(root+19)%20]);
		point p4=point(x[(root+18)%20],y[(root+18)%20]);
		if( fabs( sqrt( ( x[root] - x[(root+1)%20]) * ( x[root] - x[(root+1)%20] ) + ( y[root] -  y[(root+1)%20] ) * ( y[root] - y[(root+1)%20]) ) - 6) < = eps)
		{
			l[root]=Line(p2,p3);
			if(check(p1))printf("left\n");
			else printf("right\n");
		}
		else
		{
			l[root]=Line(p3,p2);
			if(check(p4))printf("left\n");
			else printf("right\n");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值