(二分)
题意:定于det矩阵为满足的矩阵;||X||为X所有相的绝对值的最大值。给出二阶方正A,要求||A-B||的最小值,且B满足det矩阵。
解法:从题目数据范围0~1e9我们可以通过二分答案的思路来求解答案的最小值,那么现在需要找到二分的条件。在已知答案的情况下,我们可以将答案数据与矩阵A中4个数做差,那么我们可以得到B中4个数的上下界范围,再用矩阵B的min_a*min_d求到a*d的下届,max_a*max_d得到a*d的上界,b*c的上下界同理,那么若是a*d的范围与b*c的范围存在交集(即矩阵B满足det矩阵),那么说明在ans取更小值时可以存在B矩阵满足det矩阵的情况。因此通过不断的二分即可得到min_ans,这里数据输出精度为1e-9,最大值为1e9,那么我们只需要二分答案63次以上即可得到min_ans。
代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int main() { double a, b, c, d; while (~scanf("%lf%lf%lf%lf", &a, &b, &c, &d)) { double mid, l = 0.0, r = 1e9; int t = 65; while (t--) { mid = (l + r) / 2.0; double a1 = a - mid, a2 = a + mid, d1 = d - mid, d2 = d + mid; double b1 = b - mid, b2 = b + mid, c1 = c - mid, c2 = c + mid; double L1 = min(min(a1*d1, a1*d2), min(a2*d1, a2*d2)); double R1 = max(max(a1*d1, a1*d2), max(a2*d1, a2*d2)); double L2 = min(min(b1*c1, b1*c2), min(b2*c1, b2*c2)); double R2 = max(max(b1*c1, b1*c2), max(b2*c1, b2*c2)); if (L1 <= R2&&L2 <= R1)//就算找到仍继续缩小,取尽量小的ans r = mid; else l = mid; } printf("%.9lf\n", l); } return 0; }