Matematické Fórum


1. 8. 2026 (L) Fórum bude brzy uzavřeno 😿

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: 826
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: 4647
Reputace:   248 
 

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: 4647
Reputace:   248 
 

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: 4647
Reputace:   248 
 

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: 4647
Reputace:   248 
 

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