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 21. 04. 2010 18:48

warmy
Zelenáč
Příspěvky: 23
Reputace:   
 

magický čtverec

Ahoj, nemáte někdo algoritmus na tvorbu magických čtverců n-tého řádu?

nejlépe v c nebo c++

Offline

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

#2 21. 04. 2010 19:52 — Editoval RePRO (21. 04. 2010 19:53)

RePRO
Místo: Jihlava
Příspěvky: 363
Škola: AI VŠPJ (09-12, Bc.)
Pozice: programátor
Reputace:   11 
Web
 

Re: magický čtverec

↑ warmy: Ahoj, něco jsem našel v PC v C++, samozřejmě se to dá lehce předělat i do C:

Code:

#include <iostream> 
#define MAX 15 
using namespace std; 

int main() 
{ 
  int order, n, X, Y, i, j, a[MAX][MAX], s; // základní proměnné 

  cout << "Zadej typ matice: "; 
  cin >> order; 
   
  if((!order % 2) || (order > MAX)) return -1; // taková podmínka pro ošetření přesahu

  for (i = 0; i < order; i++) 
    for (j = 0; j < order; j++) 
    a[i][j]= 0; 

  X = 0; 
  Y = order/2; 

  for (n = 1; n <= (order*order); n++) 
  { 
     a[X][Y] = n; 
     if (a[(X+order-1)%order][(Y+order+1)%order]) 
       X = (X+order+1)%order; 
     else 
       X = (X+order-1)%order, 
       Y = (Y+order+1)%order; 
  } 
   
  for (i = 0; i < order; i++) 
  { 
    cout << 'n'; 
    for (j = 0; j < order; cout << a[i][j++] << 't');  
  } 
   
  s = (1/2.0)*order*(1+order*order); 
  cout << "Soucet rad, sloupcu, diagonal = " << s; 

  system("PAUSE");
  return 0; 
}

Srdcem trochu-programátor, duší rádoby-matematik a povoláním analytik-vývojář.

Offline

 

#3 22. 04. 2010 17:19 — Editoval septolet (22. 04. 2010 17:30)

septolet
Příspěvky: 334
Reputace:   
 

Re: magický čtverec

↑ RePRO: Proč sem dáváš něco, co nefunguje? Něco si přečti o magických čtvercích http://profuvsvet.ic.cz/view.php?cisloc … 007020007, pak si spusť tvůj "program"... Navíc v proměnné s je stále 0, ať ten tvůj výtvor spustím pro různé velikosti, tak to vrací stále 0. Proč má matice stále konstantní velikost 15x15, i když třeba spustím program a zadám 5? Co třeba dynamická alokace paměti? Tohle: s = (1/2.0)*order*(1+order*order); ti bude hlásit warning, chyba to sice není, ale dbejme na čistotu kódu. Ten výpis je strašně nepřehledný. Tímto cout << a[i][j++] << 't' a cout << 'n'; si chtěl patrně říct toto cout << a[i][j++] << '\t' a cout << '\n';. Když escape sekvence, tak tam to zpětné lomítko musí být. O system("PAUSE") jsem na tomto fóru už psal, opakovat se nebudu, koho to zajímá, tak si to jistě najde.

Offline

 

#4 06. 05. 2010 06:54

Honzc
Příspěvky: 4641
Reputace:   248 
 

Re: magický čtverec

Zdravím.
Kdysi jsem se tím zabýval a mám algoritmus i řešení, ovšem pouze v Delphi(Pascal).
Přikládám konzolovou aplikaci v Delphi.

program MagCtv;

{$APPTYPE CONSOLE}

uses
  SysUtils,Math;

type TMagCtv=array of array of Integer;//natypovani pole pro magicky ctverec
var ii,jj,y,delka,pokr,konec: Integer;
    anone: string;
    vmc: TMagCtv;

function clich(n: Integer):TMagCtv;
var i,j,k: Integer;
begin
    SetLength(Result,n,n);
    i := (n-3)div 2; j := 1;
    for k := 1 to n*n do
    begin
      i := i+1; j := j-1;
      if (i=n)and(j=-1) then
      begin
        i := n-1; j := j+2;
      end
      else
      begin
        if (i=n) then
          i := 0;
        if (j=-1) then
          j := n-1;
      end;
      if Result[i,j]=0 then
        Result[i,j] := k
      else
      begin
        i := i-1; j := j+2;
        Result[i,j] := k;
      end;
    end;
end;

function c4m2(n: Integer):TMagCtv;
var i,j,k,l,m:Integer;
begin
  SetLength(Result,n,n);
  m := n div 2;
  i := (m-3)div 2; j := 1; l := 1;
  for k := 1 to m*m do
  begin
    i := i+1; j := j-1;
    if (i=m)and(j=-1) then
    begin
      i := m-1; j := j+2;
    end
    else
    begin
      if (i=m) then
        i := 0;
      if (j=-1) then
        j := m-1;
    end;
    if Result[2*i,2*j]<>0 then
    begin
      i := i-1; j := j+2;
    end;
    if j<=m div 2 then
      if (i=m div 2)and(j=m div 2) then
      begin
        Result[2*i,2*j] := l;
        l := l+1;
        Result[2*i,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j] := l;
        l := l+1;
      end
      else
      begin
        Result[2*i+1,2*j] := l;
        l := l+1;
        Result[2*i,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j+1] := l;
        l := l+1;
        Result[2*i,2*j] := l;
        l := l+1;
      end;
    if j=m div 2+1 then
      if i<>m div 2 then
      begin
        Result[2*i,2*j] := l;
        l := l+1;
        Result[2*i,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j] := l;
        l := l+1;
      end
      else
      begin
        Result[2*i+1,2*j] := l;
        l := l+1;
        Result[2*i,2*j+1] := l;
        l := l+1;
        Result[2*i+1,2*j+1] := l;
        l := l+1;
        Result[2*i,2*j] := l;
        l := l+1;
      end;
    if j>m div 2+1 then
    begin
      Result[2*i,2*j] := l;
      l := l+1;
      Result[2*i+1,2*j+1] := l;
      l := l+1;
      Result[2*i,2*j+1] := l;
      l := l+1;
      Result[2*i+1,2*j] := l;
      l := l+1;
    end;
  end;
end;

function c2nam(n: Integer):TMagCtv;
var i,j,k: Integer;
begin
  SetLength(Result,n,n);
  k := 1;
  for i := 0 to n-1 do
    for j := 0 to n-1 do
      if (j mod 4=0)or((j+1) mod 4=0) then
      if (i mod 4=0)or((i+1) mod 4=0) then
      begin
        Result[j,i] := k;
        k := k+1;
      end
      else
      begin
        Result[n-1-j,n-1-i] := k;
        k := k+1;
      end
    else
      if (i mod 4=0)or((i+1) mod 4=0) then
      begin
        Result[n-1-j,n-1-i] := k;
        k := k+1;
      end
      else
      begin
        Result[j,i] := k;
        k := k+1;
      end;
end;

function c4m(n,a,b: Integer):TMagCtv;
var i,j,k,l,m,c,d,ii,jj:Integer;
    pbi: array of array of Integer;
begin
  SetLength(Result,n,n);
  m := b;
  Setlength(pbi,m,m);
  i := (m-3)div 2; j := 1; l := 1;
  for k := 1 to m*m do
  begin
    i := i+1; j := j-1;
    if (i=m)and(j=-1) then
    begin
      i := m-1; j := j+2;
    end
    else
    begin
      if (i=m) then
        i := 0;
      if (j=-1) then
        j := m-1;
    end;
    if pbi[i,j]=0 then
        pbi[i,j] := k
    else
    begin
      i := i-1; j := j+2;
      pbi[i,j] := k;
    end;
    ii := a*i; jj := a*j;
    for c := 0 to a-1 do
      for d := 0 to a-1 do
        if (d mod 4=0)or((d+1) mod 4=0) then
          if (c mod 4=0)or((c+1) mod 4=0) then
          begin
            Result[ii+d,jj+c] := l;
            l := l+1;
          end
          else
          begin
            Result[ii+a-1-d,jj+a-1-c] := l;
            l := l+1;
          end
        else
          if (c mod 4=0)or((c+1) mod 4=0) then
          begin
          Result[ii+a-1-d,jj+a-1-c] := l;
          l := l+1;
          end
          else
          begin
            Result[ii+d,jj+c] := l;
            l := l+1;
          end;
  end;
end;

procedure UdelejMc;
var i,np,x:Integer;
    roz: array of Integer;
begin
  np := y; x := 2; SetLength(roz,0);
  if y mod 2<>0 then
    vmc := clich(y)
  else
  begin
    if y mod 4<>0 then
      vmc := c4m2(y)
    else
    begin
      while x mod 2=0 do
      begin
        x := np div 2;
        np := x;
        SetLength(roz,Length(roz)+1);
        roz[Length(roz)-1] := 2;
      end;
      if np>1 then
      begin
        SetLength(roz,Length(roz)+1);
        roz[Length(roz)-1] := np;
      end;
      if MaxIntValue(roz)=2 then
        vmc := c2nam(y)
      else
      begin
        x := 1;
        for i := 0 to Length(roz)-2 do
          x := x*roz[i];
        vmc := c4m(y,x,roz[Length(roz)-1]);
      end;
    end;
  end;
end;

begin
  pokr := 0;                         //Promenna pro moznost pokracovani
  WriteLn('-----------------------------Magicke ctverce----------------------------------');  //Uvodni vypis
  WriteLn;
  WriteLn(' Na vstupu se zada velikost magickeho ctverce nxn,');
  WriteLn(' kde n je cele cislo z intervalu <3,50> ');
  WriteLn(' Na vystupu je pak prislusny magicky ctverec');
  while pokr=0 do
  begin
    y := -1;
    WriteLn;
    //zadani rozmeru m.c.
    repeat                         //Dokud se nezada cislo porad opakujeme zadani
      try
        WriteLn;
        Write(' Zadej velikost magickeho ctverce n: ');
        ReadLn(y);
      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 <3,50>');
          y := -1;
        end;
      end;
    until y<>-1;
    if (y<3)or(y>50) then    //Pokud zadame cislo mimo interval
      repeat                      //tak to nedovolime
        WriteLn(' n musi byt cele cislo z intervalu <3,50>');
        WriteLn;
        Write(' Zadej velikost magickeho ctverce n: ');
        ReadLn(y);
      until (y>=3)and(y<=50);

    SetLength(vmc,y,y);
    delka := Length(IntToStr(y*y))+1;
    UdelejMc;

    WriteLn;
    WriteLn(' Magicky ctverec:');
    WriteLn;
    for jj := 0 to y-1 do
    begin
      for ii := 0 to y-1 do
      Write(vmc[ii,jj]:delka);
      WriteLn;
    end;

    konec := 0;
    repeat                               //Opakujeme vyzvu, dokud nenapisme a nebo n
      WriteLn;
      Write(' Novy magicky ctverec? [a/n] ');     //Chceme-li novy m.c. 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

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson