Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
Zkousel jsem sem hodit pouzitelny kod, ale zjistil jsem, ze z toho Céčka si napamatuju vubec nic, jak jsem to pet let nepouzil (naposled jsem algoritmoval program, ktery jsem potom pouzil jako maturitní praci) - ted co píšu minialgoritmy, tak ty nemaji s programováním toho mnoho společného.
Ale, v tomto případě, pokud jsou splněný předpoklady, že příslušná hlavička je, tak bych postupoval takto (napíšu to česky, nechce se mi listovat v učebnici C++ :) )
Deklarujme vstupní číslo jako int a vypočtený faktoriál jako long double (radši)
Dále prototyp funkce factorial a funkce, která převádí číslo do pole znaků (respektive jako ukazatel na pole znaků, za mainem initializovat přes new
int main(void)
nechme uzivatele zadat cislo k faktorizaci (pouzivám správný termín? nevím)
Zavolam funkci factorial, a argumentem cislo od uzivatele - spocitam faktorial. (v definici začneme for(i=num, i>0;i--) )
Zavolam funkci DoubleToStr a převedu číslo do pole znaků. // EDIT: to právě nedokážu vymyslet, i když tu funkci úspěšně používám v těch "miniprogramech"
Cyklem zjistěme počet platných číslic, tedy velikost pole a poslední index (nevim jestli jde pouzit strlen, asi ne)
Cyklem testujeme pole od konce na nuly, cyklus skončí na prvním čísle, které není 0 - zavedeme čítač nul.
cout-em vrátíme userovi počet nul, delete pole rezervovane přeš new; return 0;
Možná, časem, sem ten kód dám, až se mi bude chtít nad tím přemýšlet syntakticky (ale, jak má někdo z kolegů v podpisu, psát kód dokáže cvičená vopice, pravá věda je vymyslet jak to algoritmovat (volně přenesená citace :) )
Offline
↑ frank_horrigan:
Není potřeba psát v C, jde nám o algoritmus, ne jeho zápis. Zvládl by tvůj program 100000!? :-)
↑ byk7:
Mám-li spočítat, kolika nulami bude n! končit v desítkové soustavě, spočítal bych si, jaká budou mít prvočísla 2 a 5 exponenty v prvočíselném rozkladu n!. Je jasné proč to dělat a jak to udělat?
Offline
↑ BrozekP:
100k faktorial by to asi nezvladl, i kdyz pro zajimavost si to zkusim, ramky mam dost :D Jediny problem by mel byt omezeni typu long double, ktery muze nabyvat hodnot 10^4932 (EDIT: to jsem si přečetl), unsigned long double (? je vubec takovy datovy typ) tedy 10^9864. To opravdu nevim, jestli by pro 100k! stačilo :D Máš pravdu, s velkýma faktoriálama bys mi to rozbil na bity :)
Jinak přes ten prvočíselnej rozklad se nechytám
Offline
↑ BrozekP:
Ještě se to dá zjednodušit, že budem uvažovat jen prvočíslo 5, protože dvojka bude mít určitě vyšší exponent :-)
Offline
↑ BrozekP:
Dělat rozklad čísla n! by bylo asi zbytečné (a asi pro velká n neproveditelné), protože když budu mít vyčíslený n! tak stačí sečíst nuly.
Já myslím udělat to takto:
1.Brát postupně jednotlivá čísla od n dolů po jedné až k číslu 2. (jeden cyklus)
(tedy čísla n,n-1,n-2,...5,4,3,2)
2.U každého čísla zkoušet dělitelnost 5-ti (kolikrát je to číslo dělitelné 5-ti) a také 2-mi.
Zapisovat si (přičítat) do nějakých součtů počet dělitelů 2-mi a počet dělitelů 5-ti.
3.Potom vzít menší číslo z těchto výsledků - to je počet 0 na konci.
4.Jak už tady někdo psal počet dělitelů 2-mi bude určitě větší než počet dělitelů 5-ti, takže stačí dělit pouze 5-ti. a to do čísla 5.
5. Z toho je vidět, že stačí brát čísla končící 5-ti nebo nulou. a dělit pouze tato.
Pseudokód:
deklaruj i,n,k,pocitadlo: Integer
zadej číslo (n)
i = n mod 5
i = n-i
pocitadlo = 0
dokud i>=5 dělej
začátek cyklu
k = i
dokud k mod 5 = 0 dělej
začátek cyklu
pocitadlo = pocitadlo + 1
k = k div 5
konec cyklu
i = i-5
konec cyklu
Výstup:
Číslo n! obsahuje na konci pocitadlo nul.
Offline
↑ Honzc:
Nestačí brát pouze čísla dělitelná 5, je nutno ještě jednou započítat čísla dělitaelná 25, 125 apod.
Nechť takové, že . Pak počet nul v číselném vyjádření se rovná
kde je dolní celá část čísla .
Offline
Ještě to jde o mnoho zjednodušit:
1. n podělíme číslem 5 to je číslem 5^1 (n div 5) - dostaneme počet nul od té pětky
2. n podělíme číslem 25 to je číslem 5^2 (n div 25)-dostaneme počet nul od té 25
3. Takto postupně dělíme číslo n mocninami 5-ti až do té doby, že n div 5^x = 0.
4. Sečteme jednotlivé výsledky dělení a máme počet nul na konci.
Offline
No, napíšu svoje řešení.
1)
2)
3) najít největší takové , že platí
4) urči, kolik je tam ; ; ; ...;
Př.:
5) jak už psal kolega ↑ Pavel:, je nutné počítat s tím, že v číslech jsou pětky/-ek
označme počet nul P
6) P → výsledek
Offline
↑ byk7:
Ten bod 3. je špatně - má být 5^x<k.
Proč to dělat tak složitě.
Takto je to jednoduché
1.Nadefinuj n,k,p jako Integer (nebo Int64)
2.Zadej n (to je číslo, ze kterého se udělá faktoriál, a my máme zjistit počet nul na konci)
3. Výpočet
k = 5;
p = 0;
dokud (n div k)>0 dělej
začátek cyklu
p = p+(n div k);
k = 5*k;
konec cyklu
4. Vypiš p (to je počet nul na konci
Program v Pascalu:
program Nuly;
{$APPTYPE CONSOLE}
uses
SysUtils;
var n,k,p,pokr,konec: Integer;
anone:string;
begin
pokr := 0; //Promenna pro moznost pokracovani
WriteLn('--------------------- Nuly ve faktorialu --------------------------'); //Uvodni vypis
WriteLn;
WriteLn(' Na vstupu se zada cislo n, ze ktereho chceme zjistit faktorial.');
WriteLn(' Na vystupu je pak pocet nul na konci faktorialu z tohoto cisla n.');
while pokr=0 do
begin
n := -1;
WriteLn;
WriteLn(' Vstup');
//zadani cisla n
repeat //Dokud se nezada cislo porad opakujeme zadani
try
Write(' Zadej cislo n: ');
ReadLn(n);
except
on EInOutError do //Osetrení spatnych vstupu-napr.pismena,
begin //nebo cisla vetsi nez 2147483647 (rozsah Integer)
WriteLn(' n musi byt cele cislo z intervalu <0,2147483647>');
n := -1;
end;
end;
until n<>-1;
if (n<0)or(n>2147483646) then //Pokud zadame cislo mimo interval
repeat //tak to nedovolime
WriteLn(' m musi byt cele cislo z intervalu <0,2147483647>');
Write(' Zadej cislo n: ');
ReadLn(n);
until (n>=0)and(n<=2147483646);
WriteLn;
k := 5; //tohle je cely vypocet
p := 0;
while (n div k)>0 do
begin
p := p+(n div k);
k := 5*k;
end; //ostatni jsou opicky
WriteLn(' Vystup');
WriteLn(' Pocet nul na konci '+IntToStr(n)+'! je: '+IntToStr(p));
konec := 0;
repeat
WriteLn; //Opakujeme vyzvu, dokud nenapisme a nebo n
Write(' Nove cislo n? [a/n] '); //Chceme-li novou matici napiseme a
ReadLn(anone);
if (anone='n')or(anone='N')or(anone='a')or(anone='A') then
konec := 1
else
begin
WriteLn;
WriteLn(' Musis zadat a nebo n');
end;
until konec<>0;
if (anone='n')or(anone='N') then //V pripade ze napiseme n + ENTER - program skonci
pokr := 1;
end;
end.
Offline
↑ byk7:
Kdyby byl v nerovnosti faktoriál, tak bys tímto získal přesně počet nul v dekadickém zápise čísla . Jenže takovýto dekadický zápis máš jen málokdy k dispozici. V nerovnosti má být opravdu jenom . Pomocí součtu viz ↑ Pavel: pak získáš počet nul, aniž bys musel pracně počítat hodnotu čísla .
Offline