Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zagadka Nicolo Tartaglii - zadanie.

Ostatnio zmodyfikowano 2016-09-09 17:58
Autor Wiadomość
lukq164
Temat założony przez niniejszego użytkownika
Zagadka Nicolo Tartaglii - zadanie.
» 2016-09-09 00:58:49
Witam. Program który napisałem sprawdzałem "ręcznie" na kilku przykładach i wszystko się zgadzało, lecz w programie sprawdzającym otrzymałem wynik 2/3  (2 odpowiedzi poprawne, 1 niepoprawna).
W opisie błędu widniała taka informacja: "wczytano 'NIE', a oczekiwano '565773'". Szukałem przyczyny tego błędu w kodzie, lecz nic nie znalazłem. Stąd moje pytanie: Czy widzicie jakiś błąd w moim programie ?


Treść zadania:

W XVI wieku dwóch utalentowanych matematyków – Gerolamo Cardano i Nicolo Tartaglia – prowadziło
spór o to, kto pierwszy z nich nauczył się rozwiązywać równania trzeciego stopnia (takie jak x
3 + 3x =
14). Chociaż prawdopodobnie rację miał Tartaglia, w publicznym sporze jednak zwyciężył Cardano, którego
nazwiskiem nazwano odpowiednie wzory. Pewne znaczenie miał tu fakt, że Tartaglia przegrał (modny w owych
czasach) pojedynek na zadania matematyczne, który prowadził z uczniem Cardana, Lodovico Ferrarim. W tym
pojedynku – jak sądzimy – obaj zadawali sobie nawzajem równania do rozwiązania, lecz Ferrari opanował tę
sztukę znacznie sprawniej, a ponadto umiał rozwiązywać nawet trudniejsze równania, czwartego stopnia.
Jak Ty sprawiłbyś się w pojedynku z Tartaglią? Jego zagadki – ze względu na niechęć do używania w owych
czasach liczb ujemnych – sformułowane są następująco:
Mając dane liczby naturalne p i q, znajdź taką liczbę naturalną x, dla której
x
3 + px = q
lub ustal, że taka liczba nie istnieje.
Wejście
W pierwszym wierszu wejścia znajduje się liczba zagadek z, nie większa niż 10 000. W kolejnych wierszach
podane są zagadki, z których każda to dwie liczby naturalne p i q. Obie liczby są dodatnie, liczba p nie przekracza
1012, zaś q – 1018. Liczby są oddzielone pojedynczym odstępem, każda zagadka podana jest w osobnym
wierszu.
Wyjście
Wypisz odpowiedzi na wszystkie zagadki, w tej kolejności, w jakiej były podane na wejściu. Odpowiedź powinna
być liczbą naturalną spełniającą podane równanie. Jeśli taka liczba nie istnieje, zamiast liczby wypisz słowo
NIE.

Kod Programu:

C/C++
#include <iostream>
#include <math.h>

using namespace std;

long long rownanie( long long x, long long p )
{
    long long wyn;
    wyn = pow( x, 3 ) + x * p;
    return wyn;
}

long long stopien3( long long p, long long q )
{
    long long xMAX = pow( q,( 1 / 3.0 ) );
    if( rownanie( xMAX, p ) == q ) return xMAX;
   
    long long xMIN = 1;
    bool brak = false;
    while( xMAX > xMIN )
    {
        long long srodek =( xMAX + xMIN + 1 ) / 2;
        if( rownanie( srodek, p ) <= q ) xMIN = srodek;
        else xMAX = srodek - 1;
       
    }
    if( rownanie( xMAX, p ) == q ) return xMAX;
    else return brak;
   
}

int main()
{
    int z;
    cin >> z;
    long long p[ z - 1 ], q[ z - 1 ];
    for( int i = 0; i < z; ++i )
         cin >> p[ i ] >> q[ i ];
   
    for( int i = 0; i < z; ++i )
    {
        long long wyn = stopien3( p[ i ], q[ i ] );
        if( wyn == 0 ) cout << "NIE" << endl;
        else cout << wyn << endl;
       
    }
   
}
P-151577
Rashmistrz
» 2016-09-09 14:46:31

Po pierwsze:

równania trzeciego stopnia (takie jak 3 + 3x = ? )
Przykro mi, ale to jest funkcja liniowa, czyli pierwszego stopnia.


Tak wygląda równanie trzeciego stopnia:
ax^3+bx^2+cx+d=0,

Po drugie:

C/C++
int z;
cin >> z;
long long p[ z - 1 ], q[ z - 1 ];
for( int i = 0; i < z; ++i )
     cin >> p[ i ] >> q[ i ];

Nie ma potrzeby przechowywania wszystkich danych na raz.
Możesz przechowywać p i q dla jednego przypadku,
rozwiązać, dać odpowiedź i pobrać kolejną porcję danych.

Po trzecie:

long long p[ z - 1 ], q[ z - 1 ];
.
Nie masz miejsca na ostatnią zagadkę.

Po czwarte:

for( int i = 0; i < z; ++i )
.
Wychodzisz poza tablicę... w dwóch różnych pętlach.

Po piąte:

Szukałem przyczyny tego błędu w kodzie, lecz nic nie znalazłem.
A w ostatniej iteracji operujesz na śmieciach, czyli danych spoza tablicy.
____________________________________________________________________________

Takie równanie bardzo łatwo rozwiązać:
// operacje aplikowane są na obie strony
3 + px = q       // od Q odejmujesz 3
px = q - 3       // dzielisz (q - 3) przez p
x = (q - 3) / p  // obliczasz równanie


Na szczęście działasz na liczbach naturalnych...
BTW Nie zapomnij sprawdzić czy czasem nie ma reszty,
bo jak jest to powinieneś dać adekwatną odpowiedź. ;P
P-151586
michal11
» 2016-09-09 15:05:48
@up

równanie jest w postaci x^3 + px = q tylko lukq164 źle sformatował post.
P-151587
Rashmistrz
» 2016-09-09 15:25:40
@michal11
Poradzi sobie... Podałem mu najważniejsze rzeczy.

EDIT:
równanie jest w postaci x3 + px = q
x3 + px = q
Sam nie mam pojęcia jak to rozwiązać,
bo nie przerabiałem na matematyce jeszcze tego.
P-151588
lukq164
Temat założony przez niniejszego użytkownika
» 2016-09-09 17:58:54
Udało mi się rozwiązać problem.

@Rashmistrz

Wydaje mi się że kompilator automatycznie poprawiał moje tablice.
long long p[ z - 1 ], q[ z - 1 ];
zamieniał na:
long long p[ z ], q[ z ];

Ponieważ jak testowałem program i wpisywałem:
2
7 10
3 14
To zwracał mi wartości:
BRAK
2

Jednakże dzięki za zwrócenie uwagi na tablice.


Ogólnie problem był z tą funkcją:

C/C++
long long rownanie( long long x, long long p )
{
    long long wyn;
    wyn = pow( x,( 3.0 ) + x * p );
    return wyn;
}

Dla wielkich liczb np:
p = 741852 i q = 582681735

Wynikiem tej funkcji była liczba 582681734 (o 1 mniejsza niż powinna być)

Po konwersji tej funkcji do takiej postaci program zaczął działać poprawnie:



C/C++
long long rownanie( long long x, long long p )
{
    long long wyn;
    wyn = x * x * x + p * x;
    return wyn;
}
P-151590
« 1 »
  Strona 1 z 1