分类讨论 ---- 2021 icpc 沈阳 L Linear Fractional Transformation (思维题)

题目链接


题目大意

给你一个线性变换函数 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进行分类讨论

  1. 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)就可以直接解了

  1. 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;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值