1. 程式人生 > >CF 549H. Degenerate Matrix(二分,退化矩陣靈活題)

CF 549H. Degenerate Matrix(二分,退化矩陣靈活題)

Note

In the first sample matrix B is 

In the second sample matrix B is 

從頭到尾都理解錯了題目意思。。

題意:對A矩陣每個值做更改,使得得到的矩陣B為退化矩陣(ad-bc=0),求四個更改的差值裡的絕對值最大的差值的最小值。

我一直以為當四個差值絕對值相等的情況下才最優。。。

列舉這個差值的最大值,二分,這裡不用while(l<=r),因為是浮點數。我們就直接設定判斷100次。

求出兩個最邊界值,如果最大值>=0&&最小值<=0,那麼一定會存在某種情況使ad-bc=0,從而滿足B是退化矩陣。但要注意不能先入為主地斷定(a+mid)*(d+mid)是最大值,(a-mid)*(d-mid)是最小值。

#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define mod 1e9+7
#define ll long long
using namespace std;
int main(){
    double a,b,c,d;
    cin>>a>>b>>c>>d;
    double l=0,r=1000000000,mid;
    for(int i=0;i<100;++i){
        mid=(l+r)/2;
        double max_x=max(max((a+mid)*(d+mid),(a-mid)*(d+mid)),max((a+mid)*(d-mid),(a-mid)*(d-mid)));
        double min_x=min(min((a+mid)*(d+mid),(a-mid)*(d+mid)),min((a+mid)*(d-mid),(a-mid)*(d-mid)));
        double max_y=max(max((b+mid)*(c+mid),(b-mid)*(c+mid)),max((b+mid)*(c-mid),(b-mid)*(c-mid)));
        double min_y=min(min((b+mid)*(c+mid),(b-mid)*(c+mid)),min((b+mid)*(c-mid),(b-mid)*(c-mid)));
        if(max_x-min_y>=0&&min_x-max_y<=0)
            r=mid;
        else
            l=mid;
    } 
    printf("%.10lf\n",l);
    return 0;
}