Matematické Fórum

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

#1 18. 05. 2010 12:14

byk7
InQuisitor
Příspěvky: 4713
Reputace:   221 
 

Algoritmus

Vymyslete algoritmus, který určí,
kolika nulami končí $k!$.

Hodně štěstí


Příspěvky psané červenou barvou jsou moderátorské, šedá je offtopic.

Offline

  • (téma jako vyřešené označil(a) byk7)

#2 18. 05. 2010 13:10 — Editoval frank_horrigan (18. 05. 2010 13:20)

frank_horrigan
Příspěvky: 938
Reputace:   31 
 

Re: Algoritmus

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 :) )


The only thing worse than being wrong is staying wrong
Sun Tzu - The Art of War

Offline

 

#3 18. 05. 2010 13:45

byk7
InQuisitor
Příspěvky: 4713
Reputace:   221 
 

Re: Algoritmus

Já jsem nemyslel algoritmus pro program ale pro člověka :-)


Příspěvky psané červenou barvou jsou moderátorské, šedá je offtopic.

Offline

 

#4 18. 05. 2010 13:57

Pavel Brožek
Místo: Praha
Příspěvky: 5694
Škola: Informatika na MFF UK
Pozice: Student
Reputace:   194 
 

Re: Algoritmus

↑ 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

 

#5 18. 05. 2010 14:17 — Editoval frank_horrigan (18. 05. 2010 14:18)

frank_horrigan
Příspěvky: 938
Reputace:   31 
 

Re: Algoritmus

↑ 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


The only thing worse than being wrong is staying wrong
Sun Tzu - The Art of War

Offline

 

#6 18. 05. 2010 14:20

Wotton
Logik
Místo: Plzeň
Příspěvky: 825
Reputace:   25 
 

Re: Algoritmus

↑ 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 :-)


Dva jsou tisíckrát jeden.

Offline

 

#7 18. 05. 2010 15:17

Honzc
Příspěvky: 4549
Reputace:   241 
 

Re: Algoritmus

↑ 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

 

#8 18. 05. 2010 15:23 — Editoval Pavel (18. 05. 2010 15:25)

Pavel
Místo: Ostrava/Rychvald
Příspěvky: 1828
Škola: OU
Pozice: EkF VŠB-TUO
Reputace:   135 
 

Re: Algoritmus

↑ Honzc:

Nestačí brát pouze čísla dělitelná 5, je nutno ještě jednou započítat čísla dělitaelná 25, 125 apod.

Nechť $m\in\mathbb{N}_0$ takové, že $5^m\leq k<5^{m+1}$. Pak počet nul v číselném vyjádření $k!$ se rovná

$ \Large  \lfloor\frac k5\rfloor+\lfloor\frac k{5^2}\rfloor+\lfloor\frac k{5^3}\rfloor+\dots+\lfloor\frac k{5^m}\rfloor, $

kde $\lfloor x\rfloor$ je dolní celá část čísla $x$.


Backslash je v TeXu tak důležitý jako nekonečno při dělení nulou v tělesech charakteristiky 0.

Offline

 

#9 18. 05. 2010 15:31

Honzc
Příspěvky: 4549
Reputace:   241 
 

Re: Algoritmus

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

 

#10 18. 05. 2010 15:34

Honzc
Příspěvky: 4549
Reputace:   241 
 

Re: Algoritmus

↑ Pavel:
Však já tam také mám, že budeme dělit 5-ti dokud to dělení je celé číslo-viz.
dokud k mod 5 = 0 dělej
začátek cyklu
  pocitadlo = pocitadlo + 1
  k = k div 5
konec cyklu
Ale ten můj druhý příspěvek je ten samý co ten tvůj.

Offline

 

#11 18. 05. 2010 15:49

Pavel
Místo: Ostrava/Rychvald
Příspěvky: 1828
Škola: OU
Pozice: EkF VŠB-TUO
Reputace:   135 
 

Re: Algoritmus

↑ Honzc:

Máš pravdu, špatně jsem to přečetl.


Backslash je v TeXu tak důležitý jako nekonečno při dělení nulou v tělesech charakteristiky 0.

Offline

 

#12 18. 05. 2010 19:25 — Editoval byk7 (18. 05. 2010 19:26)

byk7
InQuisitor
Příspěvky: 4713
Reputace:   221 
 

Re: Algoritmus

No, napíšu svoje řešení.

1) $k\in\mathbb{N}_0$
2) $k!$
3) najít největší takové $x$, že platí $5^x\leq k!$
4) urči, kolik je tam $5$; $5^2$; $5^3$; ...; $5^x$
    Př.:
    $5^1\rightarrow n_1 \nl 5^2\rightarrow n_2 \nl 5^3\rightarrow n_3 \nl \vdots \nl 5^{x-1}\rightarrow n_{x-1} \nl 5^x\rightarrow n_x$
5) jak už psal kolega ↑ Pavel:, je nutné počítat s tím, že v číslech $5^2;\,5^3;\,...;\,5^x$ jsou $2;\,3;\,...;\, x$ pětky/-ek
    označme počet nul P
    $P:=x\cdot n_x+(x-1)\cdot(n_{x-1}-n_x)+(x-2)\cdot(n_{x-2}-n_{x-1})+...+2\cdot(n_2-n_3)+(n_1-n_2)$
6) P → výsledek


Příspěvky psané červenou barvou jsou moderátorské, šedá je offtopic.

Offline

 

#13 19. 05. 2010 08:09

Honzc
Příspěvky: 4549
Reputace:   241 
 

Re: Algoritmus

↑ 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

 

#14 22. 05. 2010 17:02

byk7
InQuisitor
Příspěvky: 4713
Reputace:   221 
 

Re: Algoritmus

↑ Pavel: jen mě tak napadá, nemá být v té nerovnosti $5^m\leq k!<5^{m+1}$


Příspěvky psané červenou barvou jsou moderátorské, šedá je offtopic.

Offline

 

#15 24. 05. 2010 14:49

Pavel
Místo: Ostrava/Rychvald
Příspěvky: 1828
Škola: OU
Pozice: EkF VŠB-TUO
Reputace:   135 
 

Re: Algoritmus

↑ byk7:

Kdyby byl v nerovnosti faktoriál, tak bys tímto získal přesně počet nul v dekadickém zápise čísla $k!$. Jenže takovýto dekadický zápis máš jen málokdy k dispozici. V nerovnosti má být opravdu jenom $k$. Pomocí součtu viz ↑ Pavel: pak získáš počet nul, aniž bys musel pracně počítat hodnotu čísla $k!$.


Backslash je v TeXu tak důležitý jako nekonečno při dělení nulou v tělesech charakteristiky 0.

Offline

 

#16 25. 05. 2010 10:20

byk7
InQuisitor
Příspěvky: 4713
Reputace:   221 
 

Re: Algoritmus

OK


Příspěvky psané červenou barvou jsou moderátorské, šedá je offtopic.

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson