(关于数据怎么使用,在头文件加上#include<fstream>,在int main()里加上freopen ( "data.txt" , "r" , stdin);freopen ( "1.txt" , "w" , stdout);然后运行程序,跑了之后对比之前的output.txt。具体方法:同时按住开始和R(打开运行),输入cmd回车。例如文件在F:\,在dos界面输入cd \ f:\FC 1.txt output.txt 就可以自动比对。)
数据下载链接:
http://pan.baidu.com/s/1nt0ntJb
首先这道题的eps必须是1e-12,我一开始1e-10WA了。
我是这么考虑的:
1、如果有一条直线两端y相等即直线水平,输出答案0.00。
2、如果不想交,输出0.00。
3、如果平行或重合,输出0.00。
4、判断是否遮住(这个很容易WA,我是用叉乘来判断哪个在左)
下面是取交点:
1、如果有直线斜率不存在,取交点。
2、如果直线斜率都存在,取交点。
之后记下2条直线的较高点。
面积计算公式:
先用叉乘算▷ABC面积。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<fstream>
const double eps = 1e-12;
using namespace std;
struct point {
double x, y;
point(double _x = 0, double _y = 0): x(_x), y(_y) {
}
void input() {
cin >> x >> y;
}
void output() {
cout << x << " " << y << endl;
}
};
point operator-(const point& p1, const point& p2) {
return point(p1.x - p2.x, p1.y - p2.y);
}
double cross(point p1, point p2)
{
return (p1.x * p2.y - p2.x * p1.y);
}
bool isIntersected(point s1, point e1, point s2, point e2)
{
if(
(cross(s2-s1, e1-s1) * cross(e2-s1, e1-s1) < eps) &&
(cross(s1-s2, e2-s2) * cross(e1-s2, e2-s2) < eps)
) return true;
return false;
}
point get_intersection( point a1, point a2, point b1, point b2)
{
double q1 = ( a1.y - a2.y ) / ( a1.x - a2.x );
double w1 = ( a1.y - a1.x * ( a1.y - a2.y ) / ( a1.x - a2.x ) );
double q2 = ( b1.y - b2.y ) / ( b1.x - b2.x );
double w2 = ( b1.y - b1.x * ( b1.y - b2.y ) / ( b1.x - b2.x ) );
return point ( ( w2 - w1 ) / ( q1 - q2 ) , ( w2 - w1 ) / ( q1 - q2 ) * q1 + w1 );
}
point getcross( point a1, point a2, point b1 ,point b2 )
{
point c;
c.x = a1.x;
c.y = (b1.y - b2.y) / (b1.x- b2.x) * (c.x - b1.x)+b1.y;
return c;
}
int main()
{
//freopen ( "data.txt" , "r" , stdin);
//freopen ( "output2.txt" , "w" , stdout);
int k;
point a1, a2, b1, b2, c, z, x;
cin >> k;
while( k-- )
{
a1.input();
a2.input();
b1.input();
b2.input();
if( !cross( a1 - a2 , b1 - b2 ) )
{
cout << "0.00" << endl;
continue;
}
if( !isIntersected( a1 , a2 , b1 , b2 ))
{
cout << "0.00" << endl;
continue;
}
if( a1.y == a2.y || b1.y == b2.y )
{
cout << "0.00" << endl;
continue;
}
if( a1.x == a2.x ) c=getcross(a1, a2, b1, b2);
else if( b1.x == b2.x ) c=getcross(b1,b2,a1,a2);
else c = get_intersection(a1 , a2 , b1 , b2 );
if ( a1.y > a2.y )
{
z.y = a1.y;
z.x = a1.x;
}
else
{
z.y = a2.y;
z.x = a2.x;
}
if ( b1.y > b2.y )
{
x.y = b1.y;
x.x = b1.x;
}
else
{
x.y = b2.y;
x.x = b2.x;
}
if( z.x - c.x < -eps && x.x - c.x < -eps )
{
// z in left
if( cross( z - c , x - c ) < -eps )
{
if( z.x - x.x > -eps && x.y - z.y > -eps )
{
cout << "0.00" << endl;
continue;
}
}
if( cross( x - c , z - c ) < -eps )
{
if( x.x - z.x > -eps && z.y - x.y > -eps )
{
cout << "0.00" << endl;
continue;
}
}
}
if( z.x - c.x > eps && x.x - c.x > eps )
{
// z in left
if( cross( z - c , x - c ) < -eps )
{
if( x.x - z.x < eps && z.y - x.y > -eps )
{
cout << "0.00" << endl;
continue;
}
}
if( cross( x - c , z - c ) < -eps )
{
if( z.x - x.x < eps && x.y - z.y > -eps )
{
cout << "0.00" << endl;
continue;
}
}
}
double s = abs( cross( x - c , z - c ) / 2 );
//z.output();
//c.output();
//(x - c).output(); (z - c ).output();
if( z.y - c.y <= eps || x.y - c.y <= eps )
{
cout << "0.00" << endl;
continue;
}
s = s * min( z.y - c.y , x.y - c.y ) / max( z.y - c.y , x.y - c.y );
printf( "%.2lf\n" , s + eps );
}
return 0;
}