51集训-day3-C

原题链接https://ac.nowcoder.com/acm/contest/55994/C

题目理解():

        需要找给出的坐标组成的手掌是右手掌还是左手掌。然后看图形他又说“会平移和旋转,可能是逆时针给出点也可能是顺时针给出点”但“不会放大或缩小”。这样的话就知道图形的各个边都是固定的,那我们就找几个特殊边来帮我们判断是左手掌还是右手掌。

 然后我找的边是大拇指和小拇指外边以及下面那条边(当然我们也可以找其他特殊边)。我们可以发现如果选择这三条边。那么考虑到逆时针和顺时针,他会有两种情况:6->9->8,或者8->9->6.然后我们会发现左右手掌的逆时针和顺时针遍历,他得到的边长顺序是相反的。故此我们可以看出来我们需要判断题目给的点是逆时针的还是顺时针的,然后根据它给出的点的顺序计算出是6->9->8还是8->9->6。最终我们就可以得到给出的是左右手掌。

这里有一个知识点就是,你想判断出题目画手掌的顺序是逆时针还是顺时针(也就是画图的方向),那你就至少需要3个点来帮你判断。这里判断方向的代码如下(输入的是三个点,返回是顺时针还是逆时针):(注:因为题目上不会出现三点共线,所以不会有ans==0的情况,但是如果少一个return,那么它的编译器会给你编译报错,所以else 里面的是防止报错的,和解题没关系)

bool shun_or_ni(struct node a,struct node b,struct node c)
{
	double x1=a.x,y1=a.y,x2=b.x,y2=b.y,x3=c.x,y3=c.y;
	double ans=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
	if(ans>0)
	{
		return 1;//逆时针 
	}
	if(ans<0)
	{
		return 0;//顺时针 
	} 
    else{
        return 1;
    }
}

最终完整的AC代码如下:

#include <iostream>
#include <vector>
#include<string>
#include<sstream>
#include<math.h>
#include<map>
#include<set> 
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
	double x,y;
};
double thed(struct node a,struct node b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool shun_or_ni(struct node a,struct node b,struct node c)
{
	double x1=a.x,y1=a.y,x2=b.x,y2=b.y,x3=c.x,y3=c.y;
	double ans=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
	if(ans>0)
	{
		return 1;//逆时针 
	}
	if(ans<0)
	{
		return 0;//顺时针 
	} 
    else{
        return 1;
    }
}
void solvec()
{
	int n;
	cin>>n;
	while(n--)
	{
		struct node a[20];
		int t6=0,t8=0,t9=0;
		for(int i=0;i<20;i++)
		{
			cin>>a[i].x>>a[i].y;
			if(i>0&&5.8<=thed(a[i],a[i-1])&&thed(a[i],a[i-1])<=6.2)
			{
				t6=i;
			}
			if(i>0&&7.8<=thed(a[i],a[i-1])&&thed(a[i],a[i-1])<=8.2)
			{
				t8=i;
			}
			if(i>0&&8.8<=thed(a[i],a[i-1])&&thed(a[i],a[i-1])<=9.2)
			{
				t9=i;
			} 
		}
		int sn=shun_or_ni(a[(t9+1+20)%20],a[(t9+20)%20],a[(t9-1+20)%20]);
		
	//	cout<<t6<<" "<<t9<<" "<<t8;
		if(t6%20==(t9+1)%20&&t9==(t8+1)%20)//8->9->6
		{
			if(sn==1)//顺时针 
			{
				cout<<"right"<<endl; 
			}
			if(sn==0)//逆时针 
			{
				cout<<"left"<<endl;
			}
		}
		
		if(t8%20==(t9+1)%20&&t9%20==(t6+1)%20)//6->9->8
		{
			if(sn==1)
			{
				cout<<"left"<<endl;
			}
			if(sn==0)
			{
				cout<<"right"<<endl;
			}
		}
	}
}
int main()
{
	solvec();
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值