题目链接:
题目大意:
给出一个二阶矩阵A,求一个二阶矩阵B,且|B| = 0 ,使A-B的所有项的绝对值中的最大值最小
题目分析:
首先这道题很容易想到二分答案,那么如何判断当前情况下有没有解呢?
首先如果当前的最小值为x
那么假设矩阵A
a b
c d
那么矩阵B为
a1 b1
c1 d1
那么| a1 -a | <= d,其他的也类似,那么这是a1~d1的取值范围,那么就可求出a1*d1和c1*b1的取值范围,因为求出的范围是一个连续的区间,所以只要两个区间相交,那么当前d就有解,因为d有解,那么对于x>=d一定也有解,所以二分即可
对于浮点数的二分,可以直接给出二分的次数,次数越多,复杂度越高,同样的精度也越高,复杂度是times*log(1e9);
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#define eps 1e-10
using namespace std;
int a,b,c,d;
double getMax ( double x , double y , double d )
{
double temp = (x-d)*(y+d);
temp = max ( (x-d)*(y-d) , temp );
temp = max ( (x+d)*(y-d) , temp );
temp = max ( (x+d)*(y+d) , temp );
return temp;
}
double getMin ( double x , double y , double d )
{
double temp = (x-d)*(y-d);
temp = min ( (x-d)*(y+d) , temp );
temp = min ( (x+d)*(y-d) , temp );
temp = min ( (x+d)*(y+d) , temp );
return temp;
}
bool check ( double x )
{
double l1 = getMin ( a , d , x );
double r1 = getMax ( a , d , x );
double l2 = getMin ( b , c , x );
double r2 = getMax ( b , c , x );
if ( l1 <= r2 && r1 >= l2 ) return true;
return false;
}
int main ( )
{
while ( ~scanf ( "%d%d%d%d" , &a , &b , &c , &d ) )
{
double l , r , mid;
r = max ( max ( abs(a),abs(b)) , max ( abs(c) , abs(d) ) );
l = 0;
int num = 1000000;
while ( num-- )
{
mid = (l+r)/2.0;
if ( check( mid ) ) r = mid;
else l = mid;
}
printf ( "%.10lf\n" , l );
}
}