题目大意
给你一个线性变换函数
f
(
z
)
=
a
z
+
b
c
z
+
d
f(z)=\frac{az+b}{cz+d}
f(z)=cz+daz+b,现在把取值范围扩展到复数域。给你3个等式
f
(
z
1
)
=
w
1
f(z_1)=w_1
f(z1)=w1
f
(
z
2
)
=
w
2
f(z_2)=w_2
f(z2)=w2
f
(
z
3
)
=
w
3
f(z_3)=w_3
f(z3)=w3
问你
f
(
z
0
)
f(z_0)
f(z0)是多少?
解题思路:
题目有个很有意思的地方就是它保证了解是唯一的!!
现在有3个等式只能确定3个变量,那么对于第4个变量我们是可以直接赋一个特殊值去求的?
那么最特殊的是什么呢?肯定是分母啊!
那么肯定是对分母里面的 c c c进行分类讨论
- c = 0 c=0 c=0
如果 c = 0 c=0 c=0那么 f ( z ) = a z + b d f(z)=\frac{az+b}{d} f(z)=daz+b其实 d d d就是一个常数无所谓的那么就直接把 d d d变成 ( 1 , 0 ) (1,0) (1,0)就可以直接解了
-
c
!
=
0
c!=0
c!=0
那么我们可以直接另这个 c = ( 1 , 0 ) c=(1,0) c=(1,0)反正上下有比例都是无所谓的,现在有3个变量,3个方程也可以直接接高斯消元就可以了
AC code
#include <bits/stdc++.h>
#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;
using namespace std;
/*-----------------------------------------------------------------*/
ll gcd(ll A, ll b) {return b ? gcd(b, A % b) : A;}
#define INF 0x3f3f3f3f
const int N = 3e5 + 10;
const long double eps = 1e-9;
typedef pair<int, int> PII;
typedef complex<long double> cp;
cp A[10][10];
long double mo(cp x) {
return x.imag() * x.imag() + x.real() * x.real();
}
void guss(int n) {
for(int i = 1; i <= n; i++ ){
int r = i;
for(int j = i + 1; j <= n; j++) {
if(mo(A[j][i]) > mo(A[r][i])) r = j;
}
if(r != i) swap(A[r], A[i]);
if(mo(A[i][i]) < eps) continue;
for(int j = 1; j <= n; j++) {
if(i == j) continue;
cp tmp = A[j][i] / A[i][i];
for(int k = i; k <= n + 1; k++) {
A[j][k] -= A[i][k] * tmp;
}
}
}
for(int i = 1; i <= n; i++) {
if(mo(A[i][i]) < eps) continue;
A[i][n + 1] /= A[i][i];
}
}
int main() {
IOS;
cp a, b, c;
cp z[5], w[5];
cp qz;
int t;
long double x, y;
cin >> t;
while(t--) {
for(int i = 1; i <= 3; i++) {
cin >> x >> y;
z[i].real(x);
z[i].imag(y);
cin >> x >> y;
w[i].real(x);
w[i].imag(y);
}
cin >> x >> y;
qz.real(x);
qz.imag(y);
a = (w[1] - w[2]) / (z[1] - z[2]);
b = w[1] - a * z[1];
cp res;
if(mo(a * z[3] + b - w[3]) < eps) {
res = a * qz + b;
} else {
for(int i = 1; i <= 3; i++) {
A[i][1] = z[i];
A[i][2] = cp(1, 0);
A[i][3] = -w[i];
A[i][4] = w[i] * z[i];
}
guss(3);
res = (A[1][4] * qz + A[2][4]) / (qz + A[3][4]);
}
cout << seteps(12) << res.real() << " " << res.imag() << endl;
}
}