Responsive image Boda Szilárd weblapja

Laborfeladatok 1. Tegyük fel, hogy a1, a2, a3 ... an típusú pénzérménk van, amivel S összeget kell kifizessünk. Egy backtracking program segítségével írjuk fel azt a megoldást, amikor
a) minimum számú érmével kell kifizetni az összeget
b) maximum számú érmével kell kifizetni az összeget
Feltételezzük, hogy minden pénzérméből véges számú áll a rendelkezésünkre ahhoz, hogy az S összeget kifizessük.


2. a) Egy egér egy labirintus elején van (0,0 pozicíó) s szeretne eljutni a labirintus végére (n-1, m-1 pozició) ahol egy darab sajt található, de a labirintusban valahol van egy macska.
Segítsünk neki, írva egy backtracking programot, amely az összes lehetséges utat legenerálja.
Feltételezzük, hogy az egér csak le-fel, jobbra-balra tud mozogni (tehát átlósan nem),
illetve nem kerülhet a macska közvetlen szomszédjába.
Jelöljük -2 vel a cicát, -1 el a falakat, s egy labirintus.txt állpományból olvassuk be a labirintutst, amelynek első sorában két szám van, az n és m (a labirinuts méretei), az utána következő n sorban a labirintus értékei lesznek (minden sorban m érték).

2. b) az a pontnál kapott útvonalak közül keressük meg, s írjuk ki a legrövidebbet!

3. Csöpp Báró a norokszöáj sikerén felbuzdulva eldöntötte, hogy új slágert ír, de ezúttal a "duzsmán", "bány", "jubitá", és "inimámnyá" szavakat szeretné használni. Tudva, hogy a refrén

  1. 5 szóból kell álljon
  2. 1 szó csak 2 szer ismétlődhet

segítsünk neki azáltal, hogy írunk egy backtracking programot, amely legenerálja az összes lehetséges variációt!

4. Írjunk egy backtracking programot, amely legenerál minden lehetséges módot, ahogyan felvehetjük a következő ruhadarabokat:
ing, nyakkendő, nadrág, zakó, zokni és cipő
ha a következő szabályok kell érvényesüljenek:

5. A backtracking módszert használva, írjunk egy programot, amellyel generáljuk az összes lehetőségét egy ital keverésének 4 különböző gyümölcsből az {eper, alma, sárgadinnye, körte, narancs} halmazból, ha tudjuk, hogy narancs és sárgadinnye nem lehet egyszerre a koktélban.

6. Használva a backtracking módszert, generálja le az összes lehetőséget, ahogyan négy személy ki tud fizetni 250 lejes összköltségű fogyasztást a következő kikötések mellett:

7. A backtracking módszert használva, írjunk egy programot, amellyel generáljuk az összes lehetőségét egy ital keverésének különböző gyümölcsökből az {áfolnya, kajszín, citrom, alma, körte } halmazból, ha tudjuk, hogy

8. Használva a backtracking módszert, generálja le az összes tortatípust, melyek három különböző krémréteggel rendelkeznek a következő halmazból {karamell, csokoládé, tejszín , dió, vanilía}.

9. A backtracking módszert használva, generálja le az összes 3 különböző színből alkotható zászlót, a színeket a {fehér, sárga, fekete, piros, zöld} halmazból választva.

10. Egy cég programozási nyelvekből kurzusokat szervez a {PHP, Java, Python, C++, MatLab} halmazból úgy, hogy minden személy egy páros számú nyelvet tartalmazó kurzust választhat, de nem választhatja ugyanabban a kurzusban a Java és Python nyelveket. A backtracking módszert alkalmazva generáljuk egy személy összes lehetséges opcióját, amelyet a cég kínálatából választhat


11. Egy backtracking függvény írva generáljuk le az összes megoldást amellyel a következő típusú édességekből álló dobozt létrehozhatjuk {csokigolyó, karamella, drazsé, nyalóka}.

12. A backtracking algoritmust használva állítsuk elő az összes lehetséges megoldást, ahogy 5 különböző írószerből álló csomagot kialakíthatunk a {toll, golyóstoll, ceruza, töltőtoll, ecset}, halmazból, úgy hogy minden csomagban a ceruza megelőzi a töltőtoll-at és a golyóstoll-at. Két csomag különböző, ha az elemek más sorrendbe vannak helyezve.


13. A backtracking módszert alkalmazva generáljuk az összes lehetséges módon összeállítható gyöngysort, amelyek 4 különböző színű gyöngyből állnak a {vörös, kék, rózsaszín, narancs, zöld} halmazból, úgy, hogy egyik gyöngysorban sem állhat egymásmelletti pozícióban a vörös és a kék gyöngy.

Megoldott feladatok

1. Tegyük fel, hogy a1, a2, a3 ... an típusú pénzérménk van, amivel S összeget kell kifizessünk. Egy backtracking program segítségével írjuk fel az összes lehetséges módot, ahogy ezt megtehetjük!
Feltételezzük, hogy minden pénzérméből véges számú áll a rendelkezésünkre ahhoz, hogy az S összeget kifizessük.
#include <iostream>
#include <string>
#include <vector>

int osszeg=10;
int megoldasokszama = 0;
int penzermek[] = {10, 5, 1};
int elegendo[] = {3,1, 5};
int N = 3;

using namespace std;
string megoldas = "";
/*
logikai fuggveny, amely megvizsgalja, hogy megvan e az adott osszeg
igazat terit vissza, ha igen
hamisat, ha nem
*/
bool egyenlo(int ideiglenesosszeg)
{
    if (ideiglenesosszeg == osszeg)
    {
        return true;
    }
    return false;
}
/*
logikai fuggveny, amely megvizsgalja,
hogy az adott penzermet hozza lehet e meg adni az ideiglenes osszeghez
igazat terit vissza, ha igen
hamisat, ha nem
*/
bool hozzaadhatom(int ideiglenesosszeg, int penzerme, int hanyvan)
{
    if (penzerme + ideiglenesosszeg > osszeg)
    {
        return false;
    }
    if (hanyvan < 1){
        return false;
    }
    return true;
}
/*
backtrack fuggveny,megvizsgalja, hogy a jelenlegi megoldas vegso megoldas-e.
Ha igen, akkor kiirja es kilep, ha nem, akkor probalja a kovetkezo ermet hozzaadni
*/
bool backtrack(int ideiglenesosszeg,int index, vector<int> megoldas, int eleg[])
{
    if(egyenlo(ideiglenesosszeg))
    {
        megoldasokszama++;
        for(int erme: megoldas){
            cout << erme << " " ;
            }
        cout << endl;
        return 0;
    }

    for(int i=index; i<N; i++)
    {
        if (hozzaadhatom(ideiglenesosszeg, penzermek[i], eleg[i]))
        {
            vector<int> tempmegoldas;
            for(int erme: megoldas){
                tempmegoldas.push_back(erme);
            }
            tempmegoldas.push_back(penzermek[i]);
            int tempeleg[N];
            for(int k = 0; k < N; k++){
                tempeleg[k] = eleg[k];
            }
            tempeleg[i] --;
            int temposszeg = ideiglenesosszeg+penzermek[i];
            //megoldas.append(" ");
            backtrack(temposszeg, i, tempmegoldas, tempeleg);
        }
    }
    return 0;
}
int main()
{
    vector<int> megoldas;
    backtrack(0,0, megoldas, elegendo);
    cout << "a lehetseges megoldasok szama " << megoldasokszama;
    return 0;
}

2. Egy mennyasszonynak segítségre van szüksége mennyasszonyi csokra elkészítéséhez. Kedvenc virágai a rózsa, tulipán, gerbera, orchidea és liliom, de ezekől csak 3 at szeretne a mennyaszonyi csokrában látni. Segítsünk neki azáltal, hogy írunk egy C++ programot, amelyben az összes lehetséges kombinációt legeneráljuk!
#include <iostream>
using namespace std;
int N = 3;
string virag[] = {"rozsa", "tulipan", "gerbera","orchidea", "liliom"};
/**
A lehet fuggveny, amiben csak azt kell vizsgaljuk,
hogy a megadott uj virag megvan-e mar az ideiglenes csokorban.
Ha igen, akkor hamisat terit vissza,
kulonben igazat
args:
csokor - az ideiglenes csokor, amelyikbe mar lehetnek viragok
n - az ideiglenes csokor nagysaga
ujvirag - az uj viragnak a neve, amit bele szeretnenk tenni a csokorba
*/
bool lehet(string csokor[], int n, string ujvirag)
{
//vegigmegyunk a tombon, s megnezzuk, hogy barmelyik elem megegyezik-e
//a uj viraggal, mert ha igen, akkor nem tehetjuk bele a csokorba
for(int i = 0; i<n; i++)
{
if (csokor[i] == ujvirag)
{
return false;
}
}
return true;
}
/**
Kiir fuggveny, kiir egy string tombot, aminek n a hossza
*/
void kiir(string csokor[], int n)
{
for(int i = 0; i<n; i++)
{
cout << csokor[i] << " " ;
}
cout << endl;
return;
}
/**
a backtrack fuggveny, amely megprobalja osszerakni a mennyasszonyi csokrot
args:
csokor - az ideiglenes csokor, amelyikkel probalkozunk
n - az ideiglenes csokor hossza
index - az a szam, ahanyadik viragnal tartunk a virag tombbol (pl index = 1, akkor csak a tulipant, s az azutani viragokat probaljuk a csokorba tenni)
*/
void backtrack(string csokor[], int n, int index)
{
//ha az ideiglenes csokor hossza N, amennyi viragra szuksegunk van
//akkor ez megoldas, leallunk, s kiirjuk
if (n == N)
{
kiir(csokor, n);
return;
}
//megprobaljuk az osszes lehetseges variaciot a viragokkal,
//ezert kezdjuk az elso szamnal, az indexnel, ahonnan probalkozzunk, s megyunk vegig a virag tombon
for(int i = index; i<5; i++)
{
//megvizsgaljuk. hogy bele lehet e tenni az aktualis uj viragot a mar meglevo csokorba
if (lehet(csokor, n, virag[i]))
{
//ha igen, letrehozunk egy ideiglenes csokrot, aminek N=3 lesz a hossza,
//mivel max akkora kell legyen a menyasszonyi csokrunk
string tempcsokor[N];
//atmasoljuk az eddigi csokrot az ideiglenes csokorba
for(int j = 0; j<n; j++)
{
tempcsokor[j] = csokor[j];
}
//az n-1 edik helyig másoltunk, uh a következo helyre kell tegyuk
//az uj viragot. Pl ha az eddigi csokor = {rozsa, tulipan}, akkor n = 2
//az uj csokor {rozsa tulipan gerbera} kell legyen, tehat az n. indexre kell tenni az uj viragot
tempcsokor[n] = virag[i];
//meghivjuk a backtrack fuggvenyt az uj ideiglenes csokorra, s mivel hozzaadtunk egy viragot, ezert az n et noveljuk 1 el
//mivel vizsgaljuk a lehet fuggvenyben, hogy ne legyen ket ugyanolyan virag, ezert az i erteket nem muszaj novelni.
backtrack(tempcsokor, n+1, i);
}
}
}

int main()
{
//letrehozunk egy ures csokrot, mivel meg nem tudjuk milyen viragok lesznek a menyasszonyi csokorban
string csokor[] = {""};
//mivel meg nem tettunk egy viragot sem sehova, ezert az eddigi csokorban 0 virag van, tehat n=0,
//s minden viragbol szeretnenk, ha lenne a csokorban, ezert az indexet is 0 rol inditjuk
//nezzuk meg, hogy ha 1 rol inditjuk, akkor rozsa nem lesz a csokrokban, ha 2 rol, rozsa s tulipan sem...
backtrack(csokor, 0, 0);
return 0;
}
3. Egy egér egy labirintus elelén van (0,0 pozicíó) s szeretne eljutni a labirintus végére (n-1, m-1 pozició)
Segítsünk neki, írva egy backtracking programot, amely az összes lehetséges utat legenerálja.
Feltételezzük, hogy az egér csak le-fel, jobbra-balra tud mozogni (tehát átlósan nem)
 a falakat 1 esekkel jelöljük, s egy labirintus.in állpományból olvassuk be, amelynek első sorában két szám van,
az n és m (a labirinuts méretei)

#include <iostream>
#include <fstream>

using namespace std;

//A lehetseges koordinatak legeneralasa
short xlehet[] = {0,0,-1, 1};
short ylehet[] = {-1,1, 0, 0};
/**
Fuggvent a labirintus kiirasara
*/
void kiir(int tomb[100][100], int n, int m)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cout << tomb[i][j] << " ";
}
cout << endl;
}

cout << endl;
}
/**
Lehet fuggveny, ami hamist fog visszateriteni,
ha
- falba utkozunk
- voltunk mar ott, ahova lepni szeretnenk
- kilepnenk a labirintusbol
*/
bool lehet(int tomb[100][100], int n, int m, int xpos, int ypos)
{
//ha a megadott pozicio nincs a labirintusba,
//teristsunk vissza hamisat
//elobb az x koordinatara
if (xpos <0 )
{
return false;
}
if (xpos > n-1)
{
return false;
}
//aztan az y koordinatara
if (ypos <0 )
{
return false;
}
if (ypos > m-1)
{
return false;
}
//a falat 1 essel jeloltuk, szoval ha 1 esre lepnenk,
//akkor teritsunk vissza hamisat
if (tomb[xpos][ypos] == 1)
{
return false;
}
if (tomb[xpos][ypos] == 2)
{
return false;
}
//ha semmi sem akadalyoz meg minket abban, hogy ide lepjunk, akkor teritsunk vissza igazat
return true;
}
void backtrack(int tomb[100][100], int n, int m, int xpos, int ypos)
{
//a leallasi feltetel az lesz, hogy a labirintus vegen vagyunk
if ((xpos == n-1) && (ypos == m-1))
{
kiir(tomb, n, m);
return ;
}
for(int i = 0; i<4; i++)
{

if (lehet(tomb, n, m, xpos+xlehet[i], ypos+ylehet[i]))
{

int tempxpos = xpos+xlehet[i];
int tempypos = ypos+ylehet[i];
int templabirintus[100][100];
//az ideiglenes labirintusban atmasoljuk az eger helyet
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
templabirintus[i][j] = tomb[i][j];
}

}
//az ideiglenes labirintusban frissitjuk az eger helyet
templabirintus[tempxpos][tempypos] = 2;
backtrack(templabirintus, n, m, tempxpos, tempypos);

}
}

}

int main()
{
int a[100][100];
ifstream inputfile("labirintus.in");
int n, m;
//beolvassuk az n es m erteket
inputfile >> n >> m;
//beolvassuk a labirintust
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
inputfile >> a[i][j];
}

}
//az egeret a 0 0 helyre tesszuk
//feltetelezzuk, hogy az eger helyzetet 2 essel jeloljuk
a[0][0] = 2;

//meghivjuk a backtrack fuggvenyt
backtrack(a, n, m, 0, 0);
return 0;
}