jzoj4380【GDOI2016模拟3.11】矩形

Description

有一个w*h的矩形,它两边与坐标轴平行,且矩形中心与坐标原点重合。
现将它沿原点逆时针旋转a度产生一个新的矩形,求这个新矩形与原矩形相交的面积。
详见对应样例2的图片。

 

Input

 第一行三个整数w,h,a。

 

Output

一个实数表示两个矩形相交的面积。

 

Solutions

暴力出旋转之后的矩形与原矩形所有交点,
分两种情况:8个交点和4个交点,
特判一下90°和180°就OK了。

代码

 1 uses math;
 2 var
 3   w,h,aa:int64;
 4   x1,y1,x2,y2,k,b,op,po:array [1..4] of real;
 5 function min(o,p:longint):longint;
 6 begin
 7   if o<p then exit(o);
 8   exit(p);
 9 end;
10 
11 procedure main;
12 var
13   i:longint;
14   num,top1,top2:int64;
15   a,ty,s,xx,yy,t,tk,s1,s2,xo,yo:real;
16 begin
17   ty:=aa;
18   a:=aa*3.1415926535/180; num:=0; top1:=0; top2:=0;
19   x1[1]:=-w/2; x1[2]:=-w/2; x1[3]:=w/2; x1[4]:=w/2;
20   y1[1]:=h/2; y1[2]:=-h/2; y1[3]:=-h/2; y1[4]:=h/2;
21   xx:=-w/2; yy:=h/2;
22   if a>90 then a:=(180-ty)*3.1415926535/180;
23   k[1]:=tan(a); k[2]:=-1/tan(a);
24   k[3]:=tan(a); k[4]:=-1/tan(a);
25   ty:=ty*3.1415926535/180; xo:=0; yo:=0;
26   for i:=1 to 4 do
27     begin
28       x2[i]:=x1[i]*cos(ty)-y1[i]*sin(ty);
29       y2[i]:=x1[i]*sin(ty)+y1[i]*cos(ty);
30       b[i]:=y2[i]-k[i]*x2[i];
31       if x2[i]<=x1[1] then xo:=x1[1]-x2[i];
32       if y2[i]>=y1[1] then yo:=y2[i]-y1[1];
33       if ((yy-b[i])/k[i]>=xx) and ((yy-b[i])/k[i]<=xx+w) then
34         begin
35           inc(num);
36           inc(top2); po[top2]:=(yy-b[i])/k[i];
37         end;
38       if ((yy-b[i]-h)/k[i]>=xx) and ((yy-b[i]-h)/k[i]<=xx+w) then inc(num);
39       if (k[i]*xx+b[i]<=yy) and (k[i]*xx+b[i]>=yy-h) then
40         begin
41           inc(num);
42           inc(top1); op[top1]:=(k[i]*xx+b[i]);
43         end;
44       if (k[i]*(xx+w)+b[i]<=yy) and (k[i]*(xx+w)+b[i]>=yy-h) then inc(num);
45     end;
46   if num=8 then
47     begin
48       if op[1]>op[2] then t:=op[1]-op[2]
49                      else t:=op[2]-op[1];
50       if po[1]>po[2] then tk:=po[1]-po[2]
51                      else tk:=po[2]-po[1];
52       s1:=t*xo; s2:=tk*yo;
53       s:=w*h-s1-s2;
54     end else
55     if top1>0 then
56       begin
57         if op[1]>op[2] then t:=op[1]-op[2]
58                        else t:=op[2]-op[1];
59         s:=t*w;
60       end else
61       begin
62         if po[1]>po[2] then t:=po[1]-po[2]
63                        else t:=po[2]-po[1];
64         s:=t*h;
65       end;
66   writeln(s:0:9);
67 end;
68 
69 begin
70   readln(w,h,aa);
71   if aa mod 90=0 then
72     begin
73       if aa=90 then writeln(min(w,h)*min(w,h))
74                else writeln(w*h);
75     end else
76     main;
77 end.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值