#include
<
iostream
>
using
namespace
std;
double
len,h1,h2,h3,h4;
double
sb_cal(
double
h_counter,
double
h_adj1,
double
h_adj2) {
double
hx, rebuild_V, l1, l2, rm_part_V, final_V;
if
( h_counter
<
h_adj1
+
h_adj2 )
return
-
1
;
hx
=
h_counter
-
(h_adj1
+
h_adj2);
if
( hx
<
0
)
//
有一个点为0,但其实其他三点确定了该点应该是大于0,就会出现计算到hx是负数
return
-
1
;
l1
=
(len
*
hx)
/
( hx
+
h_adj1 );
l2
=
(len
*
hx)
/
( hx
+
h_adj2 );
rebuild_V
=
((h_adj1
+
hx
+
h_counter
+
hx
+
h_adj2
+
hx)
/
4
)
*
len
*
len;
//
把整个有水的部分抬高hx
rm_part_V
=
(l1
*
l2
*
hx)
/
6
;
//
多减的部分
final_V
=
rebuild_V
-
(len
*
len
*
hx)
+
rm_part_V;
return
final_V;
}
int
cal(
double
*
v) {
double
side1,side2,ret;
if
( h1
==
0
&&
h2
==
0
&&
h3
==
0
&&
h4
==
0
||
len
==
0
) {
*
v
=
0
;
return
1
;
}
if
( h1
==
0
&&
h2
==
0
||
h2
==
0
&&
h3
==
0
||
h3
==
0
&&
h4
==
0
||
h4
==
0
&&
h1
==
0
)
return
3
;
ret
=
-
1
;
if
( h1
==
0
)
ret
=
sb_cal(h3, h2, h4);
else
if
( h3
==
0
)
ret
=
sb_cal(h1, h2, h4);
else
if
( h2
==
0
)
ret
=
sb_cal(h4, h1, h3) ;
else
if
( h4
==
0
)
ret
=
sb_cal(h2, h1, h3);
else
if
( h1
-
h2
==
h4
-
h3
&&
h1
-
h4
==
h2
-
h3 )
//
no zero 刚开始我使用长度来比较,结果wa3,因为 5, 4, 5, 4 这样的数据可以通过长度比较,但其实是不符合事实的
ret
=
(h1
+
h2
+
h3
+
h4)
/
4
*
len
*
len;
if
( ret
<
0
)
return
2
;
else
{
*
v
=
ret;
return
1
;
}
}
int
main() {
int
t,ret;
double
v;
cin
>>
t;
for
(
int
i
=
0
;i
<
t;i
++
) {
scanf(
"
%lf %lf %lf %lf %lf
"
,
&
len,
&
h1,
&
h2,
&
h3,
&
h4);
ret
=
cal(
&
v);
if
(
1
==
ret )
printf(
"
%.6f\n
"
, v);
else
if
(
2
==
ret )
printf(
"
error\n
"
);
else
printf(
"
ambiguous\n
"
);
}
return
0
;
}
纯数学题,有几个要点:
1)四个水位点在同一个平面的情况下,其容积计算公式是四个水位高度的平均值乘以底面积
2)当有一个水位点为0,其他都不为0的时候,那么为0的水位点还是可以由其他三个水位点计算出来(一个沉下去的点,前提是其他三个点的数据符合事实)
3)如果四个水位在同一平面中的话,那么总会形成一个平行四边形。

