Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // zadanie3.c -- Denis Piovarči, 20.11.2018 12:33
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define BIGNMB 300000
- int drak_pos = 0;
- int drak_z = 0;
- int princess_count = 0;
- int princess_pos[5] = { -1, -1, -1, -1, -1 };
- int generator = 0;
- int generator_pos = 0;
- //int teleport_count = 0;
- //int teleport = 0;
- int c;
- //struktura zaznam suseda
- struct zaznam_suseda {
- int destinacia;
- int cas;
- int pozicia;
- struct zaznam_suseda *dalsi_sused;
- };
- //struktura obsahujuca smernik na hlavicku zaznamu suseda
- struct susedia {
- struct zaznam_suseda *hlavicka;
- };
- //struktura reprezentujuca graf
- struct graf {
- int pocet_vrcholov;
- struct susedia *pole_susedov;
- };
- //struktura pre zaznam haldy
- struct zaznam_haldy {
- int vrchol;
- int vzdialenost;
- };
- //struktura pre haldu
- struct halda {
- int aktualna_velkost;
- int max_kapacita;
- int *pozicia;
- struct zaznam_haldy **pole;
- };
- //struktura pre teleporty
- struct teleporty {
- int vrchol;
- int cislo_teleportu;
- };
- //pole zaznamov pre teleporty
- struct teleporty *pole_t;
- //funckia, ktora vytvara graf
- struct graf *vytvor_graf(int vrcholy) {
- struct graf *graf = (struct graf*)malloc(sizeof(struct graf));
- graf->pocet_vrcholov = vrcholy;
- graf->pole_susedov = (struct susedia*)malloc(vrcholy * sizeof(struct susedia));
- for (int i = 0; i < vrcholy; i++)
- graf->pole_susedov[i].hlavicka = NULL;
- return graf;
- }
- //funkcia, ktora vytvara novy zaznam suseda
- struct zaznam_suseda *novy_zaznam_suseda(int destinacia, int cas, int pozicia) {
- struct zaznam_suseda* novy_zaznam_suseda = (struct zaznam_suseda*)malloc(sizeof(struct zaznam_suseda));
- novy_zaznam_suseda->destinacia = destinacia;
- novy_zaznam_suseda->cas = cas;
- novy_zaznam_suseda->pozicia = pozicia;
- novy_zaznam_suseda->dalsi_sused = NULL;
- return novy_zaznam_suseda;
- }
- //kazdy vrchol grafu ma svojich susedov, cez ktorych moze ist
- //tato funkcia prida ku kazdemu vrcholu susedov do pola susedov
- void pridaj_hranu(struct graf *graf, int pozicia, int destinacia, int cas) {
- struct zaznam_suseda *novy_zaznam = novy_zaznam_suseda(destinacia, cas, pozicia);
- novy_zaznam->dalsi_sused = graf->pole_susedov[pozicia].hlavicka;
- graf->pole_susedov[pozicia].hlavicka = novy_zaznam;
- }
- //funckia sluzi na vytvaranie noveho zaznamu do haldy
- struct zaznam_haldy *novy_zaznam_haldy(int vrchol, int vzdialenost) {
- struct zaznam_haldy *novy_zaznam = (struct zaznam_haldy*)malloc(sizeof(struct zaznam_haldy));
- novy_zaznam->vrchol = vrchol;
- novy_zaznam->vzdialenost = vzdialenost;
- return novy_zaznam;
- }
- //sluzi na vytvorenie MIN haldy
- struct halda *vytvor_haldu(int kapacita) {
- struct halda *MIN_halda = NULL;
- MIN_halda = (struct halda*)malloc(sizeof(struct halda));
- MIN_halda->pozicia = (int*)malloc(kapacita * sizeof(int));
- MIN_halda->aktualna_velkost = 0;
- MIN_halda->max_kapacita = kapacita;
- MIN_halda->pole = (struct zaznam_haldy**)malloc(kapacita * sizeof(struct zaznam_haldy*));
- return MIN_halda;
- }
- //funckia sluzi na upravu haldy tj, ak je treba nieco vymenit a pod. aby boli dodrzane vsetky pravidla
- void oprav_haldu(struct halda *MIN_halda, int id) {
- int minimum, lavy, pravy;
- struct zaznam_haldy *min_zaznam, *id_zaznam, *pom;
- minimum = id;
- lavy = 2 * id + 1;
- pravy = 2 * id + 2;
- if (lavy < MIN_halda->aktualna_velkost && MIN_halda->pole[lavy]->vzdialenost < MIN_halda->pole[minimum]->vzdialenost)
- minimum = lavy;
- if (pravy < MIN_halda->aktualna_velkost && MIN_halda->pole[pravy]->vzdialenost < MIN_halda->pole[minimum]->vzdialenost)
- minimum = pravy;
- if (minimum != id) {
- min_zaznam = MIN_halda->pole[minimum];
- id_zaznam = MIN_halda->pole[id];
- MIN_halda->pozicia[min_zaznam->vrchol] = id;
- MIN_halda->pozicia[id_zaznam->vrchol] = minimum;
- pom = MIN_halda->pole[minimum];
- MIN_halda->pole[minimum] = MIN_halda->pole[id];
- MIN_halda->pole[id] = pom;
- oprav_haldu(MIN_halda, minimum);
- }
- }
- //vracia haldu, ked je uplne prazdna
- int je_prazdna(struct halda *MIN_halda) {
- return MIN_halda->aktualna_velkost == 0;
- }
- //funkcia sluziaca na odstranenie minimalneho prvku z haldy
- struct zaznam_haldy *odstran_min(struct halda *MIN_halda) {
- struct zaznam_haldy *koren, *posledny_zaznam;
- if (je_prazdna(MIN_halda))
- return NULL;
- koren = MIN_halda->pole[0];
- posledny_zaznam = MIN_halda->pole[MIN_halda->aktualna_velkost - 1];
- MIN_halda->pole[0] = posledny_zaznam;
- MIN_halda->pozicia[koren->vrchol] = MIN_halda->aktualna_velkost - 1;
- MIN_halda->pozicia[posledny_zaznam->vrchol] = 0;
- --MIN_halda->aktualna_velkost;
- oprav_haldu(MIN_halda, 0);
- return koren;
- }
- //decrease key
- void zniz(struct halda *MIN_halda, int vrchol, int vzdialenost) {
- struct zaznam_haldy *pom;
- int i = MIN_halda->pozicia[vrchol];
- MIN_halda->pole[i]->vzdialenost = vzdialenost;
- while (i && MIN_halda->pole[i]->vzdialenost < MIN_halda->pole[(i - 1) / 2]->vzdialenost) {
- MIN_halda->pozicia[MIN_halda->pole[i]->vrchol] = (i - 1) / 2;
- MIN_halda->pozicia[MIN_halda->pole[(i - 1) / 2]->vrchol] = i;
- pom = MIN_halda->pole[i];
- MIN_halda->pole[i] = MIN_halda->pole[(i - 1) / 2];
- MIN_halda->pole[(i - 1) / 2] = pom;
- i = (i - 1) / 2;
- }
- }
- //funckia zistujuca ci sa dany vrchol uz nachadza v halde
- int je_v_halde(struct halda *MIN_heap, int vrchol) {
- if (MIN_heap->pozicia[vrchol] < MIN_heap->aktualna_velkost)
- return 1;
- return 0;
- }
- //dijkstra hlada najkratsiu a najefektivnejsiu cestu z jedneho vrchola do druheho
- int *dijkstra(struct graf *graf, int vychadzajuci_bod, int *cesta, int m) {
- int pocet_vrcholov = graf->pocet_vrcholov;
- int v, u, *parent;
- int *vzdialenost;
- struct zaznam_haldy *zaznam_v_halde;
- struct zaznam_suseda *pNode;
- vzdialenost = (int*)malloc(pocet_vrcholov * sizeof(int));
- parent = (int*)malloc(pocet_vrcholov * sizeof(int));
- struct halda *MIN_halda = vytvor_haldu(pocet_vrcholov);
- for (v = 0; v < pocet_vrcholov; ++v) {
- parent[0] = -1;
- vzdialenost[v] = BIGNMB;
- MIN_halda->pole[v] = novy_zaznam_haldy(v, vzdialenost[v]);
- MIN_halda->pozicia[v] = v;
- }
- MIN_halda->pole[vychadzajuci_bod] = novy_zaznam_haldy(vychadzajuci_bod, vzdialenost[vychadzajuci_bod]);
- MIN_halda->pozicia[vychadzajuci_bod] = vychadzajuci_bod;
- vzdialenost[vychadzajuci_bod] = 0;
- zniz(MIN_halda, vychadzajuci_bod, vzdialenost[vychadzajuci_bod]);
- MIN_halda->aktualna_velkost = pocet_vrcholov;
- while (!je_prazdna(MIN_halda)) {
- zaznam_v_halde = odstran_min(MIN_halda);
- u = zaznam_v_halde->vrchol;
- pNode = graf->pole_susedov[u].hlavicka;
- while (pNode != NULL) {
- v = pNode->destinacia;
- if (je_v_halde(MIN_halda, v) && vzdialenost[u] != BIGNMB && pNode->cas + vzdialenost[u] < vzdialenost[v]) {
- vzdialenost[v] = vzdialenost[u] + pNode->cas;
- parent[v] = u;
- zniz(MIN_halda, v, vzdialenost[v]);
- }
- if (pNode->pozicia == drak_pos && drak_z == 0) {
- drak_z = 1;
- return parent;
- }
- if (pNode->pozicia == generator_pos)
- generator = 1;
- /*
- int s;
- for (int i = 0; i < c; i++) {
- if (pNode->pozicia == pole_t[i].vrchol) {
- for (int j = 0; j < c; j++) {
- if (pole_t[i].cislo_teleportu == pole_t[j].cislo_teleportu) {
- s = pole_t->vrchol;
- pNode->pozicia = s;
- return parent;
- }
- }
- }
- }
- */
- /*
- if ((pNode->pos == teleport_pos[0] || pNode->pos == teleport_pos[1] || pNode->pos == teleport_pos[2]) && drak_z == 1 && generator == 1 && teleport == 0)
- {
- teleport = 1;
- teleport_pos[0] = -1;
- *cesta = princess_pos[0];
- return parent;
- }
- */
- if (pNode->pozicia == princess_pos[0] && drak_z == 1)
- {
- *cesta = princess_pos[0];
- princess_pos[0] = -1;
- return parent;
- }
- if (pNode->pozicia == princess_pos[1] && drak_z == 1)
- {
- *cesta = princess_pos[1];
- princess_pos[1] = -1;
- return parent;
- }
- if (pNode->pozicia == princess_pos[2] && drak_z == 1)
- {
- *cesta = princess_pos[2];
- princess_pos[2] = -1;
- return parent;
- }
- if (pNode->pozicia == princess_pos[3] && drak_z == 1)
- {
- *cesta = princess_pos[3];
- princess_pos[3] = -1;
- return parent;
- }
- if (pNode->pozicia == princess_pos[4] && drak_z == 1)
- {
- *cesta = princess_pos[4];
- princess_pos[4] = -1;
- return parent;
- }
- pNode = pNode->dalsi_sused;
- }
- }
- return 0;
- }
- int time(char **mapa, int x, int y) {
- switch (mapa[x][y]) {
- case 'C':
- return 1;
- case 'H':
- return 2;
- case 'N':
- return -1;
- case 'D':
- return 1;
- case 'P':
- return 1;
- case 'G':
- return 1;
- }
- if (mapa[x][y] >= '0' && mapa[x][y] <= '9')
- return 1;
- return 0;
- }
- int getWeight(char letter)
- {
- switch (letter)
- {
- case 'C':
- return 1;
- case 'H':
- return 2;
- case 'P':
- return 1;
- case 'N':
- return -1;
- case 'D':
- return 1;
- case 'G':
- return 1;
- }
- if (letter >= '0' && letter <= '9')
- return 1;
- return 0;
- }
- int *zachran_princezne(char **mapa, int n, int m, int t, int *dlzka_cesty)
- {
- int i, j, poc = 0, *dist, *path, cesta, l, k, *tmp, totalCount = 0, o, pred;
- int V = n * m;
- struct graf* graf = vytvor_graf(V);
- pole_t = (struct teleporty*)malloc(sizeof(struct teleporty));
- pole_t[0].cislo_teleportu = -1;
- pole_t[0].vrchol = -1;
- path = (int*)malloc(sizeof(int)*n*m);
- tmp = (int*)malloc(sizeof(int)*n*m);
- for (i = 0; i < n; i++)
- {
- for (j = 0; j < m; j++)
- {
- if (mapa[i][j] == 'D')
- drak_pos = poc;
- if (mapa[i][j] == 'P')
- {
- princess_pos[princess_count] = poc;
- princess_count++;
- }
- if (mapa[i][j] == 'G')
- generator_pos = poc;
- if (mapa[i][j] >= '0' && mapa[i][j] <= '9')
- {
- for (c = 0; pole_t->vrchol != -1 && pole_t->cislo_teleportu != -1; c++);
- pole_t = (struct teleporty *)realloc(pole_t, c + 1);
- pole_t[c].vrchol = poc;
- pole_t[c].cislo_teleportu = mapa[i][j];
- }
- if (j == 0 && i == 0)
- {
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j != 0 && i == 0 && j != m - 1)
- {
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j == m - 1 && i == 0)
- {
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j == 0 && i == n - 1)
- {
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j != 0 && i == n - 1 && j != m - 1)
- {
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j == m - 1 && i == n - 1)
- {
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j == 0 && i != 0 && i != n - 1)
- {
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j == m - 1 && i != 0 && i != n - 1)
- {
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- poc++;
- }
- else if (j != 0 && i != 0 && i != n - 1 && j != m - 1)
- {
- pridaj_hranu(graf, poc, poc - m, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc - 1, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + m, getWeight(mapa[i][j]));
- pridaj_hranu(graf, poc, poc + 1, getWeight(mapa[i][j]));
- poc++;
- }
- }
- }
- dist = dijkstra(graf, 0, &cesta, m);
- path[0] = 0;
- path[1] = 0;
- k = drak_pos;
- i = 1;
- while (1)
- {
- tmp[i] = k;
- i++;
- k = dist[k];
- totalCount++;
- if (k == 0)
- break;
- }
- l = totalCount;
- for (i = 1; i <= totalCount; i++) {
- path[i * 2] = tmp[l] % m;
- path[i * 2 + 1] = tmp[l] / m;
- l--;
- }
- for (j = 0; j < princess_count; j++)
- {
- if (j == 0)
- {
- dist = dijkstra(graf, drak_pos, &cesta, m);
- k = cesta;
- pred = drak_pos;
- }
- else
- {
- dist = dijkstra(graf, pred, &cesta, m);
- k = cesta;
- }
- if (cesta != -1) {
- i = 0;
- while (1)
- {
- tmp[i] = k;
- i++;
- k = dist[k];
- totalCount++;
- if (j == 0) {
- if (k == drak_pos)
- break;
- }
- else
- {
- if (k == pred)
- break;
- }
- }
- l = i - 1;
- for (o = totalCount - i + 1; o <= totalCount; o++) {
- path[o * 2] = tmp[l] % m;
- path[o * 2 + 1] = tmp[l] / m;
- l--;
- }
- pred = cesta;
- }
- else
- {
- k = 8;
- i = 0;
- while (1)
- {
- tmp[i] = k;
- i++;
- k = dist[k];
- totalCount++;
- if (j == 0) {
- if (k == drak_pos)
- break;
- }
- else
- {
- if (k == pred)
- break;
- }
- }
- l = i - 1;
- for (o = totalCount - i + 1; o <= totalCount; o++) {
- path[o * 2] = tmp[l] % m;
- path[o * 2 + 1] = tmp[l] / m;
- l--;
- }
- }
- }
- /*
- if (teleport == 1) {
- dist = dijkstra(graph, 35, &cesta, m);
- k = cesta;
- i = 0;
- while (1)
- {
- tmp[i] = k;
- i++;
- k = dist[k];
- totalCount++;
- if (k == 35)
- break;
- }
- tmp[i] = 35;
- i++;
- totalCount++;
- l = i - 1;
- for (i = totalCount - i + 1; i <= totalCount; i++) {
- path[i * 2] = tmp[l] % m;
- path[i * 2 + 1] = tmp[l] / m;
- l--;
- }
- }
- */
- *dlzka_cesty = totalCount + 1;
- return path;
- }
- int main() {
- int dlzka_cesty = 0;
- int n = 5, m = 5, t = 0;
- char **mapa = (char**)malloc(n * sizeof(char*));
- for (int i = 0; i < m; i++) {
- mapa[i] = (char*)malloc(m * sizeof(char));
- }
- mapa[0] = "CHHDC";
- mapa[1] = "HCCHH";
- mapa[2] = "CHPPC";
- mapa[3] = "PHHHC";
- mapa[4] = "CHHHC";
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- printf("%c", mapa[i][j]);
- }
- printf("\n");
- }
- zachran_princezne(mapa, n, m, t, &dlzka_cesty);
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement