Właśnie skasowałem komentarz Anonima pod tym zadaniem. Oto ten komentarz:
2016-02-24 14:48:01 anonimowy
Zadanie jest według mnie bardzo źle sformułowane, za co jednak nie
sposób winić autora - dobre jego sformułowanie uczyni go zadaniem łatwym
(banalnym?). Wyniki 0/4 i 1/4 są zrozumiałe i oznaczają, że robimy coś
bardzo źle. Wynik 2/4 oznacza, że zadanie już umie się rozwiązać i dalej
trzeba kombinować tak, aż uzyska się to, co autor miał na myśli
twierdząc, że: "do rozwiązania wystarczy 64-bitowy zakres zmiennych".
Wynik 3/4 jest jednak dość męczący: w zależności od tego, który test nie
jest zaliczany, przyczyna problemu jest inna i trudno ją wskazać.
Jeżeli ktoś nie zrozumie intencji autora (a trudno jest je pojąć mając
tylko treść zadania) to będzie tworzył cuda typu BigInt i nie będzie
miał większych szans na poprawę swojego wyniku. Wówczas może, tak jak
ja, zacząć szukać porad w Internecie. Może też, tak jak ja, trafić na
gotowca i... załamać się, że to zadanie jest tak banalne! Sporo osób nie
chce jednak na gotowca trafić a przez to rozwiązanie zadania staje się
niemałym wyzwaniem - wystarczy dodać do siebie dwa ułamki by przekonać
się, że 64-bitowa zmienna jest za mała (WA), o ile nie dokona się po
drodze wielu dziwnych zmian (które jednak dają w najlepszym przypadku
3/4). Z forum trudno pojąć, czy unsigned long long int faktycznie tu
wystarcza (ludzie piszą cuda o wielu różnych typach). W związku z tym
oraz mając na celu uchronienie zainteresowanych przed gotowcem mam mały
zestaw porad dotyczących rozwiązania (4/4):
Wystarczają long double oraz long long
NWD pozwoliło mi otrzymać 2/4, ale na 3/4 i 4/4 potrzeba było czegoś jeszcze
W zadaniu ważne jest rzutowanie, na przykład wczytanie danych
jako long double i rzutowanie ich w pewnych miejscach na long long
Wielu ludzi (a na pewno ja) usilnie starało się zmniejszać liczby
w ułamkach sądząc, że to miał na myśli autor twierdząc, że można je
zmieścić w 64 bitach. Niesłusznie - dla 3/5, 8/6 oraz 7/11 można
spokojnie rozszerzyć te liczby do znacznie większych (powiedzenie jakich
to rozwiązanie na tacy), a nie zamieniać 8/6 na 4/3, by uzyskać
możliwie małe wartości, które potem dodawałem w jakiś tam sposób
(postępując w ten sposób nie przeszedłem testu #2)
Po odpowiednich przekształceniach, które zasugerowałem powyżej,
okaże się, że ułamki można do siebie dodać bez żadnych problemów
Suma liczników, nawet po rozszerzeniu, zmieści się w odpowiednich typach danych, o ile wykona się odpowiednie przekształcenia
Rozwiązanie nie powinno zając więcej niż 100 lini kodu (wystarczy nawet około połowa).
Powodzenia!
Dlaczego usunąłem powyższy komentarz z komentarzy pod zadaniem?
Miejscem na takie wypowiedzi [i podpowiedzi] jest forum. Dajmy możliwość innym samodzielnego rozwiązywania zadania, a jeżeli już ktoś "podda się" i koniecznie będzie szukał pomocy lub gotowca, to tu jest to miejsce. Dodatkowo, wybacz Anonimowy, napisałeś w swoim komentarzu "kupę" małych głupstw i nieścisłości. Zadanie nie dlatego jest w średnich, że jest łatwe, bo nie jest. Widać to nawet z powyższego wątku i z pytania kokoska, pozostającego bez odpowiedzi aż do dziś. Tak, bo dzisiaj [dopiero] mogę definitywnie odpowiedzieć tak. W tym zadaniu, zgodnie z tym co napisał autor, wystarczy tylko i wyłącznie typ unsigned long long. A operacje skracania i doprowadzania do wspólnego mianownika, to nie żadna magia, tylko podstawowa wiedza wyniesiona z lekcji matematyki [w podstawówce?]. Deogi Anonimku, przecież typ long double nie jest typem 64 bitowym:
Uruchom w programie:
cout << "sizeof(double) = " << sizeof(double) << endl;
cout << "sizeof(long double) = " << sizeof(long double) << endl;
PS
Na pocieszenie, moje 4/4 uzyskałem prawie 4 lata temu, w podobny, karkołomny sposób, a dzisiaj twój błędny komentarz zmobilizował i zmusił mnie do przemyślenia i poprawienia go i jak napisałem użycia tylko unsigned long long i uzyskania 4/4.
PS 2
Można też użyć tylko typu long double, bez żadnych skracań i doprowadzania do wspólnego mianownika, ale należy pamiętać o skończonej dokładności [precyzji] wszystkich typów zmiennoprzecinkowych i że nie można porównywać takich wartości do zera lecz z pewnym błędem.
if (a + b <= c + 10e-15) drukuj ( NIE ) // c >= b >= a
else drukuj ( TAK )
ale i tak maks jaki udało mi się w ten sposób uzyskać to 3/4, zmieniając wartość błędu 10e-15 na mniejsze i większe wartości.
PS 3
Anonimowy. Jak na razie powinieneś brać poprawkę na swoje programy nie dwa ale trzy
. 100 linii kodu / 3. Przecież chyba już Ci wysyłałem jakiś mój program?