湖南程序设计竞赛赛题总结 XTU 1237 Magic Triangle(计算几何)

这个月月初我们一行三人去湖南参加了ccpc湖南程序设计比赛,虽然路途遥远,六月的湘潭天气燥热,不过在一起的努力之下,拿到了一块铜牌,也算没空手而归啦。不过通过比赛,还是发现我们的差距,希望这几个月自己努力思考,积极刷题,为九月份acm网络赛做准备!

言归正传说说这道题目,这也是这次比赛想到AC比较高的题目,不过我们还是没能完成,下面我就来总结一下此题的一些思路和方法。

Magic Triangle

Problem Description:

Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU.

Huangriq works in a big company in Guangzhou now, all things goes well but the mosquitos are too disturbing. Mosquito net and mosquito-repellent incense are useless for this mosquito city.

And finally he decides to use magic to kill them. He make a magic regular triangle as the picture shows. While the most proper position to launch magic is not always the center of circle. In order to make everything smoothly, Huangriq needs to get the value of  . And he already get two of them, can you help him to figure out the rest one?

Input

The first line contains a integer T(no more than 10000), which indicates the number of test cases. In the following T lines, each line contains two integers a and b () indicating the two angle Huangriq has already got.

Output

For each test case, output the rest angle's value with two digits after a decimal point in one line.

Sample Input

1
30 30

Sample Output

30.00

计算几何

求直线交点——叉积的应用

直线的一般方程为F(x) = ax + by + c = 0。

既然我们已经知道直线的两个点,假设为(x0,y0), (x1, y1),那么可以得到

a = y0 – y1, b = x1 – x0, c = x0y1 – x1y0

因此我们可以将两条直线分别表示为

F0(x) = a0*x + b0*y + c0 = 0, F1(x) = a1*x + b1*y + c1 = 0

那么两条直线的交点应该满足

a0*x + b0*y +c0 = a1*x + b1*y + c1

由此可推出

x = (b0*c1 – b1*c0)/D

y = (a1*c0 – a0*c1)/D

D = a0*b1 – a1*b0,(D为0时,表示两直线平行)

二者实际上就是连立方程组F0(x) = a0*x + b0*y + c0 = 0, F1(x) = a1*x + b1*y + c1 = 0的叉积应用

i     j     k

a0   b0   c0

a1   b1   c1

XTU 1237 Magic Triangle

此题的求解角度的思路,用到了高中向量计算的常用方法,建立直角坐标系,利用两向量点乘的逆运用。

即下面两个公式:

解决此题也同时认识到了思路不能太局限,就像出题人所说求角就只去推角的关系,这样就输了,转个思路运用向量解决几何的问题是很重要的手段!!!

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #define PI acos(-1.0)
 6 using namespace std;
 7 struct point
 8 {
 9     double x;
10     double y;
11 };
12 point readpoint(double x,double y)
13 {
14     point c;
15     c.x=x;
16     c.y=y;
17     return c;
18 }
19 point readinsertion(point t0,point t1,point k0,point k1)
20 {
21     point o;
22     double a0,b0,c0,a1,b1,c1,d;
23     a0=t0.y-t1.y;
24     b0=t1.x-t0.x;
25     c0=t0.x*t1.y-t1.x*t0.y;
26     a1=k0.y-k1.y;
27     b1=k1.x-k0.x;
28     c1=k0.x*k1.y-k1.x*k0.y;
29     d=a0*b1-a1*b0;
30     o.x=(b0*c1-b1*c0)/d;
31     o.y=(a1*c0-a0*c1)/d;
32     return o;
33 }
34 double ins(point a,point b)//求向量的模
35 {
36     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
37 }
38 double dot(point a,point o,point b)//两向量坐标相乘
39 {
40     return (o.x-a.x)*(o.x-b.x)+(o.y-a.y)*(o.y-b.y);
41 }
42 double readAngle(point a,point o,point b)//向量点乘的逆运用
43 {
44     return acos(fabs(dot(a,o,b))/(ins(a,o)*ins(b,o)));
45 }
46 int main()
47 {
48     int t,a,b;
49     cin>>t;
50     while(t--)
51     {
52         cin>>a>>b;
53         double k1,k2,k3;
54         double r;
55         k1=tan((60-a)*1.0/(180/PI));//求两个直线方程的斜率
56         k2=tan((180-b)*1.0/(180/PI));
57         point a,b,c,d,e,o;
58         a=readpoint(1,sqrt(3.0));//建立直角坐标系(A,B,C)
59         b=readpoint(0,0);
60         c=readpoint(2,0);
61         d=readpoint(2,k1*2);//在求一个该直线方程上的点
62         e=readpoint(0,-2*k2);
63         o=readinsertion(b,d,c,e);//求交点
64         r=readAngle(o,a,c)*180/PI;//求夹角
65         printf("%.2lf\n",r);
66     }
67     return 0;
68 }

 

posted @ 2015-06-21 11:57  fancy_boy  阅读(449)  评论(0编辑  收藏  举报