"중산 Jizhong는 지방 선거 세트 D4T1 훈련"굴절 상처 가우스 소거법

제목 설명

N 게임의 영웅, 인공 지능 부상하여 각 영웅의 초기 값이 있으며, 모든 영웅은 자신의 피해를 줄이고, 다른 사람에게 피해의 일부를 공유 할 수있는 기술, "굴절", 즉이있다. 각 굴절 관계를 위해, 우리는 수 사용 \ ((x_i로부터, y_i, z_i ) \) 나타내는 \ (x_i로부터 \) 자신의 상처의 제거 대상이 될 것입니다 (z_i \) \ 이러한 부상의 비율이 전송됩니다 \ (y_i \를 ) (\ (x_i로부터는 y_i는 \) 의 정수이며, \는 (z_i \) )의 실수이다.

각각 주인공의 단부 고통 후의 실내 반복 굴절 후의 총 데미지 계산.

입력 형식

양수의 첫 줄 : \ N- (\) , 표현 (\ N- \) 영웅 번째 행 \ (\ N-) 정수 \ (A_I는 \) 순차적 입은 주인공 각각의 초기 손상을 도시. 세 번째 행의 양의 정수 (\ m의 \)은 , 표현 (\ m의 \) 굴절률의이. 다음 \ (m의 \) 행, 세 개의 숫자의 각 행 (\ x_i로부터, y_i, z_i \) 나타내고, \을 (x_i로부터 \) 자신이 제거 상처한다 (z_i \) \을 비율이 부상에 전송한다 (\ y_i \) .

출력 형식

출력 \ (n \) 라인의 \ (내가 \) 라인이 나타내는 \을 (I \) 총 실제 피해 입은 마지막 영웅. 여섯 소수점을 예약.

견본

샘플 입력

3
1 0 2
3
1 2 0.3000
1 2 0.2000
2 1 0.5000

샘플 출력

0.666667
0.333333
2.000000

데이터 범위

데이터 범위

문제 해결

설정 \ (D_i \) 부상 후 평가로 는 (i \) \ 결국 피해가, \이 (C_I \) 하는 (내가 \) \ 총 피해, 고통을 자신의 실제 손상의 비율 \ (T_ {I, J를 } \) 대표 \ (I는 \) 하는 합계 점 (J \) \ 비율 부상.
그래서 \ (D_i이 \) 피해의 첫 번째 천국에 추가 \ (A_I \) : 다른 부상은 다른 사람으로부터 평가됩니다, 당신은 쉽게 공식 시작할 수 있습니다
\ [\ FRAC {} {C_I D_i을 } = \ sum_ {≠ j 개의 I } \ {FRAC D_j C_J} {} \ cdot T_ {J, I} + A_I \]

이 직접 설립 식에 따라 \ (D_i \) 식 및 가우스 소거법하는 방정식을 해결한다.

\(암호:\)

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 205
#define M 20005
#define eps 1e-6
int n, m, A[N];
long double val[N][N], mat[N][N];
long double ans[N];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &A[i]), val[i][i] = 1;
    int x, y;
    double c;
    scanf("%d", &m);
    for (int i = 1; i <= m; i++)
    {
        scanf("%d%d%lf", &x, &y, &c);
        val[x][y] += c;
        val[x][x] -= c;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            if (i != j)
                mat[i][j] = -val[j][i] / val[j][j];
        mat[i][i] = 1 / val[i][i];
        mat[i][n + 1] = -A[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = i + 1; j <= n; j++)
            if (fabs(mat[j][i]) > eps)
            {
                for (int k = i; k <= n + 1; k++)
                    swap(mat[i][k], mat[j][k]);
                break;
            }
        long double s = mat[i][i];
        for (int j = i; j <= n + 1; j++)
            mat[i][j] /= s;
        for (int j = i + 1; j <= n; j++)
        {
            s = mat[j][i];
            for (int k = i; k <= n + 1; k++)
                mat[j][k] -= s * mat[i][k];
        }
    }
    ans[n + 1] = 1;
    for (int i = n; i >= 1; i--)
        for (int j = i + 1; j <= n + 1; j++)
            ans[i] -= mat[i][j] * ans[j];
    for (int i = 1; i <= n; i++)
        printf("%.6lf\n", double(ans[i]));
}

추천

출처www.cnblogs.com/ModestStarlight/p/11299362.html