Problem z zadaniem ze SOPJ'a - "funkcja kwadratowa".

Odpowiedz Nowy wątek
2017-08-13 00:03
0

Mimo prawidłowych wyników, program nie jest akceptowany przez sędziego.
Tutaj link do zadania: http://pl.spoj.com/problems/ROWNANIE/

#include <iostream>
 
using namespace std;
 
int main()
{
    int l_test, wynik[100];
    cin >> l_test;
    for(int i=0; i<l_test; i++)
    {
 
        float a, b, c;
        cin >> a >> b >> c;
 
        if((b*b)-4*a*c == 0) { wynik[i] = 1; }
        else if ((b*b)-4*a*c < 0) { wynik[i] = 0; }
        else if ((b*b)-4*a*c > 0) { wynik[i] = 2; }
 
    }
 
    for(int i=0; i<l_test; i++)
    {
        cout << wynik[i] << endl;
    }
 
}

Zakładam, że problem tyczy się: "Na wejście programu podana zostanie pewna nieokreślona, ale niewielka ilość zestawów danych...". Ale czym jest ta pewna, nieokreślona ilość zestawów (założyłem, że będzie ich do 100), i czy dobrze podaję ją na wejściu?

Pozostało 580 znaków

2017-08-13 00:33
1

Nie wiem czy to przyczyna problemu, ale nie musisz pamiętać wszystkich wyników, możesz je wypluwać na bieżąco i wczytywać kolejny zestaw danych.

Pozostało 580 znaków

2017-08-13 00:46
0

hmm, przerobiłem na wersję bez zapamiętywania, i też nie przechodzi - "przekroczono limit czasu". Czy ze względu na nieskończoną pętlę?

#include <iostream>
 
using namespace std;
 
int main()
{
    int wynik;
 
    while(1)
    {
            float a, b, c;
            cin >> a >> b >> c;
 
            if((b*b)-4*a*c == 0) { wynik = 1; }
            else if ((b*b)-4*a*c < 0) { wynik = 0; }
            else if ((b*b)-4*a*c > 0) { wynik = 2; }
 
            cout << wynik << endl;  
    }
 
    return 0;
}
edytowany 2x, ostatnio: crassman22, 2017-08-13 01:19

Pozostało 580 znaków

2017-08-13 01:18
1

Tak, musisz przerobić wczytywanie danych tak, aby gdy napotka pustą linię skończył działanie, a nie wisiał na cin.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


edytowany 1x, ostatnio: nie100sowny, 2017-08-13 01:19

Pozostało 580 znaków

2017-08-13 01:19
0
nie100sowny napisał(a):

Tak, musisz przerobić wczytywanie danych tak, aby gdy napotka pustą linię skończył działanie, a nie wisiał na cin.

Okej, udało się. Powinni doprecyzować polecenie. Przechodzi kiedy while(licznik<10) , ale while(licznik<100) już nie chciało przyjąć.

Pozostało 580 znaków

2017-08-13 01:22
0

Zrozum, że masz zmienną ilość linii. Więc musisz wykryć pustą linię. Zamień cin na scanf, który zwraca -1 gdy osiągnął koniec.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


Pozostało 580 znaków

2017-08-13 01:45
0

Jeśli będę inkrementować ustawiony licznik, to w końcu natrafi na pustą linię.

edytowany 1x, ostatnio: crassman22, 2017-08-13 01:47

Pozostało 580 znaków

2017-08-13 06:43
sig
1

Zadanie w których nie wiadomo ile będzie zestawów, robisz tak

#include <iostream>
 
using namespace std;
 
int main()
{
 
    float a, b, c;
    while(cin >> a >> b >> c)
    {
            int wynik;
            if((b*b)-4*a*c == 0) { wynik = 1; }
            else if ((b*b)-4*a*c < 0) { wynik = 0; }
            else if ((b*b)-4*a*c > 0) { wynik = 2; }
 
            cout << wynik << endl;
    }
 
    return 0;
}

Pozostało 580 znaków

2017-08-13 08:31
2

po co ten copy paste, lepiej by bylo dodac sobie zmienna d = b*b - 4 * a * c

Pozostało 580 znaków

2017-08-13 09:36
3

klasyczny przykład złego porównywania liczb zmiennoprzecinkowych, przykład gdzie wynikiem mają być same jedynki:
https://wandbox.org/permlink/yT6yDvJqVVRYLNwv
Pamiętaj, że liczby zmiennoprzecinkowe mają ograniczoną precyzję więc możesz porównywać liczby, które powinny być równe, ale różnią się z powodu ograniczeń precyzji.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22, 2017-08-13 13:11

Pozostało 580 znaków

2017-08-13 13:42
0

Akruat w tym przypadku porównanie do zera za pomocą "==" jest jak najbardziej rozsądne - wynika ze wzoru na x1 i x2, gdzie z delty bierze się pierwiastek i gdy delta == 0, to dla wprowadzonych danych nie ma dwóch rozwiązań, a jedno. Dodajmy też, że dla |a| < 1 pierwiastek aktualnie zwiększa wartość liczby (przykład: a = 0.81, sqrt(a) = 0.9), co dodatkowo odsuwa nas od epsilona maszynowego. Problemem, który nakreślił przedmówca jest użycie błędnych danych wejściowych - tzn. takich, które nie zmieszczą się w reprezentacji (0.1 to ułamek okresowy w systemie binarnym).

Na poparcie moich słów, fragment faktoryzacji LU w LAPACKu: http://www.netlib.org/lapack/[...]d1/dfc/dgetrf2_8f_source.html
Linijka 178, porównywanie elementu na diagonali z 0. Robione dokładnie za pomocą ".EQ.". Stabilność numeryczną gwarantuje się w takim przypadku pivotowaniem.

popatrz na link jaki dałem i zweryfikuj swój "rozsądek". - MarekR22 2017-08-13 14:14
Ale zdajesz sobie sprawę, że dane, które podałeś na wejściu komputer zamieni na 0.1 + E1, 0.6 + E2, 0.9 + E3 i to nie jest kwestia "=="? - kapojot 2017-08-13 15:17
Przeczytałeś ze zrozumieniem co napisałem? Ten temat jest regularnie wałkowany na forum, a skoro od roku jesteś zarejestrowany to już powinieneś wiedzieć o co chodzi, oraz że jestem jedną z paru osób, które najczęściej wytykają i tłumaczą ten problem. Ponieważ wiem na czym polega problem potrafię wymyślić dane testowe, które go pokazują. - MarekR22 2017-08-13 18:08
a jeszcze proste pytanie, zaliczyłeś to zadanie? Ja tak, za pierwszym podejściem, co widać w logach. - MarekR22 2017-08-13 18:13
Oczywiście, że zaliczyłem. - kapojot 2017-08-13 19:05
Dodam jeszcze, że zawodowo zajmuję się numeryką, a problemy z porównywaniem do 0 za pomocą fabs/== są kwestią wysoce zależną od kontekstu. - kapojot 2017-08-13 19:06

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0