[C++] Iloczyn liczb naturalnych spełniających warunek


(Jooooooozek) #1

Czesc,

Miałem wykonać takie zadanie w C++:

I chciałbym się zapytać czy dobrze je wykonałem:

#include using namespace std;

(Kawior1+Dobreprogramy) #2

Wygląda na to że jest ok.

na końcu funkcji main brakuje

return 0;

No i nie masz tu sumy tylko iloczyn, może powiesz że to czepianie się nazw zmiennych ale lepiej nazywać je tak aby coś znaczyły a nie były mylące jak w tym wypadku.


(Jooooooozek) #3

A, OK dzięki :wink:


(Tomek Matz) #4

Potrzebne są poprawki. Po pierwsze w zadaniu jest powiedziane, że d musi być większe bądź równe 2. Nigdzie nie sprawdzasz jaką wartość podał użytkownik. Poza tym u Ciebie w kodzie, np dla d=3 iloczyn będzie równy 1, tymczasem wynik powinien wynieść 0. Dodatkowo pętlę mógłbyś napisać w ten sposób: n=d;n>=1;n-- i w momencie, gdy warunek będzie niespełniony to robić break w pętli (bo po co sprawdzać warunek dla pozostałych liczb naturalnych skoro już wiemy, że dla tej danej liczby naturalnej warunek jest niespełniony). Dodatkowo mógłbyś ten warunek tak przekształcić, żebyś zawsze miał liczby całkowite, czyli zamiast n^2/2 - n >= d zrobić n^2 - 2n >= 2d


([alex]) #5

matzu , iloczyn zerowej liczby elementów wynosi 1.

Stąd: pow(X,0) == 1

Czyli powinno być coś w rodzaju:

int main()

(Blapiter) #6

Więc rozumuje że zawsze pracujemy na liczbach naturalnych. Więc trzeba sprawdzić czy ta liczba

czyli

jest podzielna przez 2 zanim się ją podda rachunkowi mnożenia.

int mnoz_naturalne(int liczba)

{

	if(liczba <= 1)

	return 0;


	bool niepodzielna;

	int wynik=1;


	for(int i = liczba; i >=2 ; --i)

	{

		niepodzielna = (i & 1) > 0;

		if(!niepodzielna && (((i*i)>>1)-i) >= liczba)

		wynik *= i;

	}

	return wynik > 1 ? wynik : 0;

}

(Tomek Matz) #7

Fakt, masz rację. Ale błąd :stuck_out_tongue:


(Jooooooozek) #8


([alex]) #9

Bo o 3 nad ranem kiepsko mózgownica działa.


(Jooooooozek) #10

A też tak zapytam z ciekawości - po co w ogóle przekształcałeś to równanie, skoro to nie ma znaczenia z punktu matematycznego ?


(Tomek Matz) #11

Z matematycznego punktu widzenia nie, ale dlaczego masz tak zrobić to pisałem o tym wyżej. Dzięki takiemu przekształceniu będziesz operował zawsze na liczbach całkowitych i dzięki temu nie ma tutaj miejsca na żaden błąd przy porównywaniu liczb. Zobacz jaką wartość uzyskasz dla np. n=5, gdy użyjesz warunku (n*n)/2-n. Dostaniesz 7, a tymczasem wynik tego działania to 7.5. Żeby dostać poprawny wynik musiałbyś zapisać to w ten sposób: (n*n)/2.0-n. Ale wówczas miałbyś porównywanie liczby zmiennoprzecinkowej z całkowitą, tak więc lepiej to od razu tak przekształcić, żeby po obu stronach nierówności mieć zawsze liczbę całkowitą.


(Jooooooozek) #12

OK, dzięki.

Ale [alex] podał trochę złe rozwiązanie, ponieważ sprawdzanie czy liczba spełnia ten warunek powinno się odbywać w ifie wewnątrz pętli. Gdy to jest jako warunek pętli, to wystarczy że jeden raz liczba nie spełni warunku i koniec prób - a przecież inne mogą spełnić...

Ostateczne rozwiązanie:

#include using namespace std;

(Tomek Matz) #13

Rozwiązanie, które zaproponował [alex] jest jak najbardziej poprawne. Zastanawiam się, czy w ogóle czytałeś mój przedostatni post -,-. Jeśli np. dla n=7 warunek nie jest spełniony, to po co wykonywać sprawdzenia na n=6,5,4 itd. skoro wiemy, że dla nich też warunek nie będzie spełniony (po lewej stronie nierówności zawsze będziemy uzyskiwać co raz mniejszą liczbę). Spójrz na ten początkowy warunek i podstaw sobie kilka liczb.