The determinant of a matrix 2 × 2 is defined as follows:
A matrix is called degenerate if its determinant is equal to zero.
The norm ||A|| of a matrix A is defined as a maximum of absolute values of its elements.
You are given a matrix . Consider any degenerate matrix B such that norm ||A - B|| is minimum possible. Determine||A - B||.
The first line contains two integers a and b (|a|, |b| ≤ 109), the elements of the first row of matrix A.
The second line contains two integers c and d (|c|, |d| ≤ 109) the elements of the second row of matrix A.
Output a single real number, the minimum possible value of ||A - B||. Your answer is considered to be correct if its absolute or relative error does not exceed 10 - 9.
1 2 3 4
0.2000000000
1 0 0 1
0.5000000000
In the first sample matrix B is
In the second sample matrix B is
觉得很好的一道题,题目链接:http://codeforces.com/contest/549/problem/H
题意:
给你一个2*2的矩阵A,让你构造一个矩阵B,矩阵B要满足两条对角线元素相乘结果相等,使得 ||A-B|| 值最小。||X||表示矩阵X中的4个元素中值最大的元素。
分析:
枚举增量(发现有很多二分都是枚举增量的),判断是否符合条件,然后缩小范围。
code:
- #include<bits/stdc++.h>
- using namespace std;
- typedef long double LD;
- int a, b, c, d;
- LD f1(int m1, int m2, LD x)
- {
- return max(max((m1+x)*(m2+x),(m1+x)*(m2-x)),max((m1-x)*(m2+x),(m1-x)*(m2-x)));
- }
- LD f2(int m1, int m2, LD x)
- {
- return min(min((m1+x)*(m2+x),(m1+x)*(m2-x)),min((m1-x)*(m2+x),(m1-x)*(m2-x)));
- }
- int Check(LD x)
- {
- LD pr = f1(a,d,x); //(a..)*(d..) 与 (c..)*(b..) 比较,把它比作第一段和第二段,然后进行比较,是否会有等值情况
- LD pl = f2(a,d,x);
- LD qr = f1(c,b,x);
- LD ql = f2(c,b,x);
- if(pr < ql || qr < pl) return 0; //如果第一段与第二段不相交,则扩大两边使其可能相交
- else return 1; //如果已经相交,那么减小增量x使得两边缩小,更靠近结果
- } //这里我说得相交是将最大值与最小值看做两个点,连成的一条线段,最后两条线段的位置关系(yy的。。)
- //相交的部分代表值相等
- int main()
- {
- scanf("%d%d%d%d", &a,&b,&c,&d);
- LD l=0, r=1e10;
- for(int i=0; i<200; i++)
- {
- LD mid = 0.5*(l+r);
- if(Check(mid)) r = mid;
- else l = mid; //增量x增大,那么结果的两边(最大值与最小值)会相应往两边扩(更大、更小)
- }
- printf("%.10f\n", (double)(0.5*(l+r)));
- return 0;
- }
做完上面这道题后,把本来一直不会做的下面这道题给秒了。。
序列变换
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 625 Accepted Submission(s): 305
我们定义从序列A到序列B变换的代价为 cost(A,B)=max(|Ai−Bi|)(1≤i≤N) 。
请求出满足条件的最小代价。
注意,每个元素在变换前后都是整数。
对于每一组:
第一行为序列A的长度 N(1≤N≤105) ,第二行包含N个数, A1,A2,...,An .
序列A中的每个元素的值是正整数且不超过 106 。
第一行输出:"Case #i:"。i代表第 i 组测试数据。
第二行输出一个正整数,代表满足条件的最小代价。
2 2 1 10 3 2 5 4
Case #1: 0 Case #2: 1
- #include<stdio.h>
- int T, n, a[100010], b[100010];
- bool Check(int x)
- {
- for(int i=0; i<n; i++) b[i] = a[i];
- b[0] -= x;
- for(int i=1; i<n; i++)
- {
- int temp1 = b[i-1]-b[i]+1;
- int temp2 = b[i]-b[i-1]-1;
- if(b[i] <= b[i-1])
- {
- if(temp1 > x) return false;
- else b[i] = b[i-1]+1;
- }
- else
- {
- if(temp2 <= x) b[i] = b[i-1]+1;
- else b[i] -= x;
- }
- }
- return true;
- }
- int main()
- {
- scanf("%d", &T);
- for(int t=1; t<=T; t++)
- {
- scanf("%d", &n);
- for(int i=0; i<n; i++)
- scanf("%d", a+i);
- int l = 0, r = 1e6, mid;
- for(int i=0; i<20; i++)
- {
- mid = (l+r)/2;
- if(Check(mid)) r = mid;
- else l = mid;
- }
- printf("Case #%d:\n%d\n", t,r);
- }
- return 0;
- }