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

Zdravím, mám dvourozměrné pole 5 x 5. Mám vypsat "šneka" (šnekem se myslí toto, výpis čísel pole červené čáře)
program vypis_sneka;
uses crt;
type t_pole=array[1..5,1..5]of integer;
const pole:t_pole=((1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5));
n=5; {velikost strany ctverce (pole)}
begin
end.Napadlo mě to dělat jako každá strana vlastní for-cyklus (8 for-cyklů, docela děsivé) a navíc potřebuju řešení pro různě velké pole. Takže tudy asi cesta nevede. :(
Poradí někdo jak na to? Předem děkuji.
Offline
Rozdělil bych to na několik podúloh. Udržoval bych indexy i a j. Měl bych funkce
tiskni_políčko_pod
tiskni_políčko_vpravo
tiskni_políčko_vlevo
tiskni_políčko_nad
Každá z nich by předem upravila i nebo j a daný prvek pak vypsala.
Šnek drží směr, tedy tiskne doprava, pak dolů, pak doleva, pak nahoru a tak pořád dokola. Kolik znaků? No, když ošetřím zvlášť jeho "první řádek", pak je to vždy "dvakrát stejně".
Celkem tedy jeden cyklus vnořený do druhého, vnější s 'a' od n-1 do 1, vnitřní dvakrát za sebou vždy pro 'b' od 1 do 'a'. Při každém dokončení každého ze dvou vnitřních cyklů cyklicky změnit směr výpisu pod->vlevo->nad->vpravo->pod->...
Jistě by šlo i mít pomocnou matici, kde by se pamatovalo, která políčka se už tiskla a tiskount v daném směru tak dlouho, dokud se nenarazí na už tisknuté políčko. V tom případě cyklicky změnit směr, jak jsem ukázal výše. A celé tak dlouho, dokud je co tisknout. Ale to mi přijde malinko míň šikovné...
Offline
Mne napadl ještě způsob se "zmenšováním rámečku"
Mám horní,dolní,levý, pravý okraj, rekurzivně bych pak jezdil dokola ..doPrava(); dolu(); atd.. a při každém průjezdu zvětšil rámeček, takže by to jezdilo jako had uvnitř krabice, která se zmenšuje, dokud se nezmenší na jedno políčko.
edit: Pokud má někdo zájem o tohle řešení, sepsal jsem ho v C#
edit2: řešení postnuto níže.
Offline

↑ musixx:
Zdá se mi, že jsme si nerozuměli. Nejde o to tiskout jako šneka, ale tisknout normálně na řádek jakoby se ten šnek rozmotával.
S mým polem
const pole:t_pole=((1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5),(1,2,3,4,5));
by to bylo: 1 2 3 4 5 5 5 5 5 4 3 2 1 1 1 1 2 3 4 4 4 3 2 2 3
Offline

↑ jindra:
Netuším, jak by to řešení mohlo vypadat
Pokud má někdo zájem o tohle řešení, sepsal jsem ho v C#
Jestli by si byl tak moc hodný a zveřejnil ho možná by mi to pomohlo, třeba bych přišla na princip toho, co popisuješ.
Offline
Kdybych víc dělal v Pascalu, tak bych ti mohl pomoci více, ale moc jsem se mu nikdy nevěnoval. Některé věci by v mém řešení šli ještě zjednodušit, třeba kontrola konce.
//definování proměných
public static int pravyOkraj = 5;
public static int levyOkraj = 0;
public static int dolniOkraj = 5;
public static int horniOkraj = 0;
public static string[,] pole;
public static int posX = 0;
public static int posY = 0;
static void Main(string[] args)
{
//vytvoření dvojrozměrného pole
pole = new string[5, 5];
//prvni sloupec
pole[0,0] = "a";
pole[0,1] = "a";
pole[0,2] = "a";
pole[0,3] = "a";
pole[0,4] = "a";
//druhy sloupec
pole[1, 0] = "b";
pole[1, 1] = "b";
pole[1, 2] = "b";
pole[1, 3] = "b";
pole[1, 4] = "b";
pole[2, 0] = "c";
pole[2, 1] = "c";
pole[2, 2] = "c";
pole[2, 3] = "c";
pole[2, 4] = "c";
pole[3, 0] = "d";
pole[3, 1] = "d";
pole[3, 2] = "d";
pole[3, 3] = "d";
pole[3, 4] = "d";
pole[4, 0] = "e";
pole[4, 1] = "e";
pole[4, 2] = "e";
pole[4, 3] = "e";
pole[4, 4] = "e";
doPrava();
Console.ReadLine();
}
//Procházení polem
static void doPrava()
{
while(posX<pravyOkraj)
{
Console.WriteLine(pole[posX,posY]);
posX++;
}
posX--;
posY++;
horniOkraj++;
if (check())
{
return;
}
dolu();
}
static void dolu()
{
while (posY < dolniOkraj)
{
Console.WriteLine(pole[posX, posY]);
posY++;
}
posY--;
posX--;
pravyOkraj--;
if (check())
{
return;
}
doLeva();
}
static void doLeva()
{
while (levyOkraj-1<posX)
{
Console.WriteLine(pole[posX, posY]);
posX--;
}
posX++;
posY--;
dolniOkraj--;
if (check())
{
return;
}
nahoru();
}
static void nahoru()
{
while (horniOkraj-1 < posY)
{
Console.WriteLine(pole[posX, posY]);
posY--;
}
posY++;
posX++;
levyOkraj++;
if (check())
{
return;
}
doPrava();
}
//Kontrola jestli už jsme na konci, šlo by taky použít počítání vypsaných položek a když se budou rovnat počtu prvků v poli, tak ukončit.
static bool check()
{
if(dolniOkraj-horniOkraj==0 && pravyOkraj-levyOkraj==0)
{
return true;
}
else
{
return false;
}
}Offline