[C++] Algorytm z kotem, zmniejszający się ciąg


(Hirszq) #1

Z góry przepraszam za niejasną nazwę tematu, ale kompletnie nie wiem jak to nazwać.

Wprowadzenie: moja wiedza z programowania w C++ jest znikoma. Jednak mój nowy nauczyciel postanowił uzależnić moją ocenę końcową od pracy z C++ (niejako miał rację, bo ta wiedzę powinienem posiadać, lecz poprzedni nauczyciel nie zrealizował tematu. Ale to nieważne). Zamiast się poddać zacząłem się uczyć języka, lecz wciąż nijak się ma do poniższego zadania. Próbowałem na wiele sposobów dzisiaj, ostatni jest całkiem idiotyczny i przyznaję się, że nie jestem w stanie tego zrobić. Prosiłbym jednakże o wskazówki lub konkretną wiedzę jaką powinienem posiąść by takie zadanie zrobić. Zależy mi, bym sam potrafił zadanie tego typu wykonać:

Kot w ciągu doby śpi, bawi się i przemieszcza. Zakładamy, że o północy kot zasypia i śpi przez 2 godziny. Następnie przez 15 minut bawi się w jednym miejscu, po czym przez kolejne 45 minut przemieszcza się z prędkością 30 metrów na minutę. Potem znów idzie spać i cykl powtarza się aż do zakończenia doby, przy czym każdy etap (sen, zabawa, ruch) kolejnego cyklu trwa 5% krócej niż w cyklu poprzednim. Jaki dystans pokonuj kot w ciągu doby?

Mój ostatni program (cały zły pewnie, kompilowałem w Dev-C++):

#include 

#include 


using namespace std;


int main(int argc, char *argv[])

{

    int spanie=7200;

    int zabawa=900;

    int ruch=4050;

    int spanie2, zabawa2, ruch2;

    int I;

    int rucho=0;

    int droga;



for(int rucho, I; I<=86400; I=spanie2+zabawa2+ruch2,rucho+ruch2)

{


        spanie2=spanie*0.95;

        zabawa2=zabawa*0.95;

        ruch2=ruch*0.95;


        }


        droga=rucho/60*30;


        cout<<"Kot przeszedl w ciagu doby ";

        cout<
        cout<<" metrow\n\n";



    system("PAUSE");

    return EXIT_SUCCESS;

}

Szybciej kombinowałem z różnymi pętlami, rekurencją, bibliotekami time czy jakoś tak (żeby uniknąć jak w powyższym zapisu w sekundach jako int). Byłbym wdzięczny za wszelakie rady. :slight_smile:


(Tomek Matz) #2

Jest trochę rzeczy do poprawy.

  1. Zadanie możesz liczyć operując na minutach. Zamiast int-ów powinieneś użyć typu zmiennoprzecinkowego np. float (bo przecież później mnożysz przez 0.95), czyli deklarujesz sobie: float spanie = 120, float zabawa = 45 oraz float ruch = 15. Zmienne spanie2, zabawa2 oraz ruch2 są niepotrzebne. Tak samo nie rozumiem co to za zmienna rucho. Powinieneś natomiast zadeklarować zmienną float ruchCalkowity, czy cos takiego (najlepiej uzywaj angielskich nazw, np. moveTimeTotal).

  2. W pętli wykonujesz między innymi takie działanie spanie2=spanie*0.95. Ono jest błędne. W końcu w treści zadania masz podane, że czas każdego kolejnego cyklu skraca się o 5%, czyli powinno być spanie = spanie * 0.95 (można to zapisać krócej spanie *= 0.95, to jest to samo), zabawa *= 0.95 oraz ruch *= 0.95. Czyli jak słusznie zauważyłeś masz tu do czynienia z pewnym ciągiem (jest to ciąg geometryczny), w którym a_n = a_(n-1) * 0.95

  3. U Ciebie warunkiem zakończenia pętli jest gdy całkowity czas wszystkich cykli przekroczy bądź będzie równy dobie. To jest prawie OK. Zauważ, że musisz ten kod napisać tak, żeby pętla kończyła się dokładnie w momencie, gdy czas będzie równy dobie. Może być przecież sytuacja, że powiedzmy w którymś cyklu wyjdzie Ci, że kot przemieszczał się 3 minuty, ale z tego tylko 2 powinny być doliczone do całkowitego czasu jaki się przemieszczał, bo ta 1 minuta już przekroczy dobę (trochę zakręciłem, ale mam nadzieję, że mnie zrozumiesz).

  4. Na koniec całkowitą drogę będziesz mógł policzyć jako droga = czas całkowity * predkosc (czyli to 30).

EDIT:

Jeśli nauczyciel Ci narzucił, że obliczenia powinny być wykonywane w sekundach, to nie powinieneś ręcznie przeliczać 120 minut na sekundy tylko zapisać float spanie = 120 * 60; Ale wtedy też będziesz musiał przeliczyć prędkość z metrów na minutę na metry na sekundę (czyli po prostu dzielić początkową wartość przez 60).


([alex]) #3

Zadanie można rozwiązać na dwa sposoby.

  1. Sposób brutal force:

    include using namespace std;


(Tomek Matz) #4

@[alex]

Mi w tym zadaniu wychodzi 10,70 km (po zaokrągleniu do dwóch miejsc po przecinku).


([alex]) #5

Bo prędkość nie wiedzieć czemu postawiłem 30 km/h. Już poprawiłem.


(Hirszq) #6

Tak, miałem na początku spanie=spanie *0,95 lecz w toku prób zmieniłem to. Byłem świadomy, że czas jednego cyklu może przekroczyć dobę i ten sposób nie jest zbyt precyzyjny, lecz nie widziałem alternatyw( nawet myślałem coś o rozdzieleniu na kilka pętli z różnymi czynnościami i późniejszej podsumie w pętli głównej..jakoś tak). Nauczyciel nie narzucał żadnej metody wykonania tego, zrobiłem to na sekundach bo nie wiedziałem jak inaczej, a nie na minutach bo właśnie myślałem o mnożeniu przez to 0,95 i o tym że int to całkowita ale później zagubiłem się i użyłem int przy sekundach.

Dziękuję za wszystkie odpowiedzi, zabieram się za to zadanie. Wykonawszy je pomyślę już bez "ocenowego stresu" nad innymi by jednak rozwinąć umiejętności. Raz jeszcze dziękuję :slight_smile:


([alex]) #7

Przy pewnych parametrach np. wszystko to samo tylko że nie 5% zaś 12.500001 (wystarczy większy od 12.5) i już zadanie nie ma rozwiązania, ponieważ nawet suma nieskończonej ilości okresów (Sen+Zabawa+Bieg) wynosi mniej niż doba.