HDU 4097 - Triangles and Quadrangle

 

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4097

 

就是将两个三角形组合成一个四边形。

 

枚举所有可能的组成即可。

 

有两种组合方式:

           一、两个三角形各选出一条边,拼在一起,并且两边相等,此时可以形成一个四边形;

           二、两个三角形各选出一个角,拼在一起,使得两角之和为180度,此时也是一个四边形。(见代码中最后一个样例)

 

比较坑的是,这题的四边形可能退化为三角形。 即两种组合方式同时发生。

 

请看代码中的最后一组测试数据。 

 

训练赛中,被这个数据一直卡到最后没出来。(其实比赛过程中有想到,然后总以为这个数据我已经过了,所以没有测试,一直怀疑是思路问题或者代码漏洞)。

 

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>

using namespace std;

const double pi = acos(-1.0);

long long s1[6],s2[6],s[10];
double a1[6],a2[6],ag[10];
long long X1,X2,X3,Y1,Y2,Y3,X4,Y4;

const double eps=1e-5;

long long dis(long long a,long long b)
{
	return a*a+b*b;
}

double angle(long long a,long long b,long long c)
{
	return acos((double)(a+b-c)/(2*sqrt((double)a*b)));
}

void input()
{
	cin>>X1>>Y1;
	cin>>X2>>Y2;
	cin>>X3>>Y3;
	s1[0]=s1[3]=dis(X1-X2,Y1-Y2);
	s1[1]=s1[4]=dis(X2-X3,Y2-Y3);
	s1[2]=s1[5]=dis(X3-X1,Y3-Y1);
	a1[0]=a1[3]=angle(s1[2],s1[1],s1[0]);
	a1[1]=a1[4]=angle(s1[2],s1[3],s1[1]);
	a1[2]=a1[5]=angle(s1[1],s1[3],s1[2]);
//	cout<<"1--"<<endl;
//	for(int i=0;i<6;i++) cout<<i<<" "<<s1[i]<<" "<<a1[i]<<endl;
	cin>>X1>>Y1;
	cin>>X2>>Y2;
	cin>>X3>>Y3;
	s2[0]=s2[3]=dis(X1-X2,Y1-Y2);
	s2[1]=s2[4]=dis(X2-X3,Y2-Y3);
	s2[2]=s2[5]=dis(X3-X1,Y3-Y1);
	a2[0]=a2[3]=angle(s2[2],s2[1],s2[0]);
	a2[1]=a2[4]=angle(s2[2],s2[3],s2[1]);
	a2[2]=a2[5]=angle(s2[1],s2[3],s2[2]);
//	cout<<"2--"<<endl;
//	for(int i=0;i<6;i++) cout<<i<<" "<<s2[i]<<" "<<a2[i]<<endl;
	cin>>X1>>Y1;
	cin>>X2>>Y2;
	cin>>X3>>Y3;
	cin>>X4>>Y4;
	s[0]=s[4]=dis(X1-X2,Y1-Y2);
	s[1]=s[5]=dis(X2-X3,Y2-Y3);
	s[2]=s[6]=dis(X3-X4,Y3-Y4);
	s[3]=s[7]=dis(X4-X1,Y4-Y1);
	ag[0]=ag[4]=angle(s[0],s[1],dis(X1-X3,Y1-Y3));
	ag[1]=ag[5]=angle(s[1],s[2],dis(X2-X4,Y2-Y4));
	ag[2]=ag[6]=angle(s[2],s[3],dis(X1-X3,Y1-Y3));
	ag[3]=ag[7]=angle(s[3],s[0],dis(X2-X4,Y2-Y4));
//	cout<<"3--"<<endl; 
//	for(int i=0;i<8;i++) cout<<i<<" "<<s[i]<<" "<<ag[i]<<endl;
}

int scs(long long a,long long b,long long c,long long d,double e,double f)
{
	int i;
	for(i=0;i<4;i++)
	{
		if(s[i]==a && s[i+1]==b && s[i+2]==c && s[i+3]==d && fabs(e-ag[i])<eps && fabs(f-ag[i+2])<eps)
		{
			return 1;
		}
	}
	return 0;
}

int scs2(long long a,double b,long long c,double e,double f,int choose)
{
	int i;
//	cout<<a<<" "<<b<<" "<<c<<endl;
	if(choose)
	{
		for(i=0;i<4;i++)
		{
			if(s[i]==a && fabs(sqrt((double)s[i+1])+sqrt((double)s[i+2])-b)<eps && s[i+3]==c && fabs(e-ag[i])<eps && fabs(f-ag[i+2])<eps)
			{
				return 1;
			}
			if(s[i]==c && fabs(sqrt((double)s[i+1])+sqrt((double)s[i+2])-b)<eps && s[i+3]==a && fabs(f-ag[i])<eps && fabs(e-ag[i+2])<eps)
			{
				return 1;
			}
		}
	}
	else
	{
		for(i=0;i<4;i++)
		{
			if(s[i]==a && fabs(sqrt((double)s[i+1])-b)<eps && s[i+2]==c && fabs(e-ag[i])<eps && fabs(f-ag[i+1])<eps)
			{
				return 1;
			}
			if(s[i]==c && fabs(sqrt((double)s[i+1])-b)<eps && s[i+2]==a && fabs(f-ag[i])<eps && fabs(e-ag[i+1])<eps)
			{
				return 1;
			}
		}
	}
	return 0;	
}

int pd()
{
	int i,j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			if(s1[i]==s2[j])
			{
				if(scs(s1[i+1],s1[i+2],s2[j+1],s2[j+2],a1[i],a2[j])) return 1;
				if(scs(s1[i+1],s1[i+2],s2[j+2],s2[j+1],a1[i],a2[j])) return 1;
				if(scs(s1[i+2],s1[i+1],s2[j+1],s2[j+2],a1[i],a2[j])) return 1;
				if(scs(s1[i+2],s1[i+1],s2[j+2],s2[j+1],a1[i],a2[j])) return 1;
			}
			if(fabs(a1[i]+a2[j]-pi)<eps)
			{
				if(scs2(s1[i],sqrt((double)s1[i+1])+sqrt((double)s2[j+1]),s2[j],a1[i+2],a2[j+2],s1[i+2]==s2[j+2])) return 1;
				if(scs2(s1[i],sqrt((double)s1[i+1])+sqrt((double)s2[j+2]),s2[j],a1[i+2],a2[j+1],s1[i+2]==s2[j+1])) return 1;
				if(scs2(s1[i],sqrt((double)s1[i+2])+sqrt((double)s2[j+1]),s2[j],a1[i+1],a2[j+2],s1[i+1]==s2[j+2])) return 1;
				if(scs2(s1[i],sqrt((double)s1[i+2])+sqrt((double)s2[j+2]),s2[j],a1[i+1],a2[j+1],s1[i+1]==s2[j+1])) return 1;
			}
		}
	}
	return 0;
}

int main()
{
	int cas,t;
	cin>>t;
	for(cas=1;cas<=t;cas++)
	{
		input();
		if(pd())
		{
			cout<<"Case #"<<cas<<": Yes"<<endl;
		}
		else
		{
			cout<<"Case #"<<cas<<": No"<<endl;
		}
	}
	return 0;
}


/*
8

0 2 0 1 1 0 
0 2 -2 0 0 1
0 2 1 0 0 1 -2 0

0 2 0 1 1 0
-1 0 -2 2 0 0
0 2 1 0 0 1 -2 0

0 2 0 1 1 0
0 2 2 0 0 1
0 2 1 0 0 -1 -2 0

0 2 1 0 0 -1 
0 2 0 -1 1 0
0 2 1 0 0 -1 -1 0

0 -1 0 2 1 0
0 2 0 -1 1 0
0 2 1 0 0 1 -1 0

0 0 2 2 0 2
0 2 1 2 0 3
0 0 2 2 1 2 0 3
 
0 0 1 0 -1 1
1 0 3 2 4 0
0 0 4 0 3 2 2 1

-1 0 0 0 0 1
0 0 0 1 3 0
0 1 -1 0 2 0 3 0

=================


ans:

Y
Y
N
Y
N
Y
Y
Y

*/


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值