@IgorMan

Как обработать все случаи при решении системы линейных уравнений с двумя неизвестными?

Добрый день всем.

Прошу прощения за мой несколько глупый вопрос, но у меня возникла проблема при подготовке к олимпиаде. Конкретно проблемы вот с этой вот задачей про систему уравнений с двумя неизвестными.
Глохну на 34 тесте.

Казалось бы, все просто:
1 случай (коэффициенты при переменных непропорциональны) gif.latex?a&space;%5Ccdot&space;d&space;Здесь система имеет однозначное решение.

2 случай (коэффициенты при переменных пропорциональны):
Этот случай разбивается на два:
а) коэффициенты при переменных и свободные члены пропорциональны
gif.latex?e&space;%5Ccdot&space;d&space;
б) коэффициенты при переменных и свободные члены пропорциональны
Тут просто решений нет, так как прямые параллельны.

Рассматриваю случай а) подробнее, так как требуется выводить разные значения исходя из возможных пар (x, y).
1. Все коэффициенты при переменных равны 0 и свободные члены равны 0 - бесконечное число решений
2. Все коэффициенты при переменных равны 0, но какой-то из свободных членов 0 не равен - решений нет
3. Когда коэффициенты при X равны 0 - тогда у нас есть единственное решение для Y, а X может быть любым
4. Когда коэффициенты при Y равны 0 - тогда у нас есть единственное решение для X, а Y может быть любым
5. Ненулевые коэффициенты, тогда решение у нас представляется в виде Y = k * X + B

Все это я реализовал на C++, код представлен ниже:
int main() {
    double a, b, c, d, e, f;
    double x, y;
    const int no_roots = 0;
    const int kx_roots = 1;
    const int one_xy_root = 2;
    const int one_x = 3;
    const int one_y = 4;
    const int inf_roots = 5;

    cin >> a >> b >> c >> d >> e >> f;

    double det = a * d - b * c;
    double det_x = (e * d - b * f);
    double det_y = (a * f - e * c);
    bool x_null = a == 0 && c == 0;
    bool y_null = b == 0 && d == 0;

    if (det != 0) {
        x = det_x / det;
        y = det_y / det;
        cout << one_xy_root << ' ' << x << ' ' << y;
    }
    else {
        if (det_x == 0 && det_y == 0) {
            if (x_null && y_null) {
                if (e != 0 || f != 0) {
                    cout << no_roots;
                }
                else {
                    cout << inf_roots;
                }
            }
            else if (x_null) {
                if (b != 0) {
                    y = e / b;
                }
                else {
                    y = f / d;
                }

                cout << one_y << ' ' << y;
            }
            else if (y_null) {
                if (a != 0) {
                    x = e / a;
                }
                else {
                    x = f / a;
                }

                cout << one_x << ' ' << x;
            }
            else {
                double bi, k;

                if (b != 0) {
                    bi = e / b;
                    k = -a / b;
                }
                else {
                    bi = f / d;
                    k = -c / d;
                }

                cout << kx_roots << ' ' << k << ' ' << bi;
            }
        }
        else {
            cout << no_roots;
        }
    }

    return 0;
}


Что я упускаю из вида? Не могу подобрать такие коэффициенты, на которых программа выдавала бы некорректный ответ.
  • Вопрос задан
  • 1980 просмотров
Пригласить эксперта
Ответы на вопрос 2
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
Для решения систем удобнее пользоваться матрицами, и методом Крамера в частности. Это не так страшно, как выглядит. И код получится намного проще и логичней.
Ответ написан
Mrrl
@Mrrl
Заводчик кардиганов
if (a != 0) {
                    x = e / a;
                }
                else {
                    x = f / a;
                }

Если a==0, будет деление на 0. Но, возможно, ошибки есть где-то ещё.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы