Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.92 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define BIGNMB 300000
  6.  
  7. int drak_pos = 0;
  8. int drak_z = 0;
  9. int princess_count = 0;
  10. int princess_pos[5] = {-1, -1, -1, -1, -1};
  11. int generator = 0;
  12. int generator_pos = 0;
  13. int teleport_pos[3] = {-1,-1,-1};
  14. int teleport_count = 0;
  15. int teleport = 0;
  16.  
  17. struct listNode
  18. {
  19. int dest;
  20. int weight;
  21. int pos;
  22. struct listNode *next;
  23. };
  24.  
  25. struct list
  26. {
  27. struct listNode *head;
  28. };
  29.  
  30. struct Graph
  31. {
  32. int V;
  33. struct list *array;
  34. };
  35.  
  36. int getWeight(char letter)
  37. {
  38. switch(letter)
  39. {
  40. case 'C':
  41. return 1;
  42. case 'H':
  43. return 2;
  44. case 'P':
  45. return 1;
  46. case 'N':
  47. return -1;
  48. case 'D':
  49. return 1;
  50. case 'G':
  51. return 1;
  52. }
  53.  
  54. if(letter >= '0' && letter <= '9')
  55. return 1;
  56.  
  57. return 0;
  58. }
  59.  
  60. struct Graph *createGraph(int n, int m)
  61. {
  62. int i;
  63. struct Graph *graph = (struct Graph*)malloc(sizeof(struct Graph));
  64. graph->V = n*m;
  65.  
  66. graph->array = (struct list*)malloc(sizeof(struct list) * n * m);
  67.  
  68. for(i=0;i<n*m;i++)
  69. graph->array[i].head = NULL;
  70.  
  71. return graph;
  72. }
  73.  
  74. struct listNode *newList(int dst, int weight, int pos)
  75. {
  76. struct listNode* newNode = (struct listNode*)malloc(sizeof(struct listNode));
  77. newNode->dest = dst;
  78. newNode->weight = weight;
  79. newNode->pos = pos;
  80. newNode->next = NULL;
  81.  
  82. return newNode;
  83. }
  84.  
  85. void addEdge(struct Graph *graph, int src, int dst, int weight)
  86. {
  87. struct listNode *newNode = newList(dst, weight, src);
  88. newNode->next = graph->array[src].head;
  89. graph->array[src].head = newNode;
  90. }
  91.  
  92. struct minHeapNode
  93. {
  94. int v;
  95. int dist;
  96. };
  97.  
  98. struct minHeap
  99. {
  100. int size;
  101. int capacity;
  102. int *pos;
  103. struct minHeapNode **array;
  104. };
  105.  
  106. struct minHeapNode *newMinHeapNode(int v, int dist)
  107. {
  108. struct minHeapNode *min_heap_node = (struct minHeapNode*)malloc(sizeof(struct minHeapNode));
  109. min_heap_node->v = v;
  110. min_heap_node->dist = dist;
  111. return min_heap_node;
  112. }
  113.  
  114. struct minHeap *createMinHeap(int capacity)
  115. {
  116. struct minHeap *min_heap = NULL;
  117. min_heap = (struct minHeap*)malloc(sizeof(struct minHeap));
  118. min_heap->pos = (int*)malloc(capacity*sizeof(int));
  119. min_heap->size = 0;
  120. min_heap->capacity = capacity;
  121. min_heap->array = (struct minHeapNode**)malloc(sizeof(struct minHeapNode*) * capacity);
  122. return min_heap;
  123. }
  124.  
  125. void minHeapify(struct minHeap *min_heap, int id)
  126. {
  127. int smallest, left, right;
  128. struct minHeapNode *smallestNode, *idNode, *tmp;
  129. smallest = id;
  130. left = 2 * id + 1;
  131. right = 2 * id + 2;
  132.  
  133. if(left < min_heap->size && min_heap->array[left]->dist < min_heap->array[smallest]->dist)
  134. smallest = left;
  135.  
  136. if(right < min_heap->size && min_heap->array[right]->dist < min_heap->array[smallest]->dist)
  137. smallest = right;
  138.  
  139. if(smallest != id)
  140. {
  141. smallestNode = min_heap->array[smallest];
  142. idNode = min_heap->array[id];
  143.  
  144. min_heap->pos[smallestNode->v] = id;
  145. min_heap->pos[idNode->v] = smallest;
  146.  
  147. tmp = min_heap->array[smallest];
  148. min_heap->array[smallest] = min_heap->array[id];
  149. min_heap->array[id] = tmp;
  150. minHeapify(min_heap, smallest);
  151. }
  152. }
  153.  
  154. int isEmpty(struct minHeap *min_heap)
  155. {
  156. return min_heap->size == 0;
  157. }
  158.  
  159. struct minHeapNode *takeMin(struct minHeap *min_heap)
  160. {
  161. struct minHeapNode *root, *lastNode;
  162.  
  163. if (isEmpty(min_heap))
  164. return NULL;
  165.  
  166. root = min_heap->array[0];
  167. lastNode = min_heap->array[min_heap->size - 1];
  168. min_heap->array[0] = lastNode;
  169.  
  170. min_heap->pos[root->v] = min_heap->size-1;
  171. min_heap->pos[lastNode->v] = 0;
  172.  
  173. --min_heap->size;
  174. minHeapify(min_heap, 0);
  175.  
  176. return root;
  177. }
  178.  
  179. void decrease(struct minHeap *min_heap, int v, int dist)
  180. {
  181. struct minHeapNode *tmp;
  182. int i = min_heap->pos[v];
  183. min_heap->array[i]->dist = dist;
  184.  
  185. while(i && min_heap->array[i]->dist < min_heap->array[(i-1)/2]->dist)
  186. {
  187. min_heap->pos[min_heap->array[i]->v] = (i-1)/2;
  188. min_heap->pos[min_heap->array[(i-1)/2]->v] = i;
  189.  
  190. tmp = min_heap->array[i];
  191. min_heap->array[i] = min_heap->array[(i-1)/2];
  192. min_heap->array[(i-1)/2] = tmp;
  193.  
  194. i = (i-1)/2;
  195. }
  196. }
  197.  
  198. int isInMinHeap(struct minHeap *min_heap, int v)
  199. {
  200. if(min_heap->pos[v] < min_heap->size)
  201. return 1;
  202. return 0;
  203. }
  204.  
  205. int *dijkstra(struct Graph *graph, int src, int *cesta, int m)
  206. {
  207. int V = graph->V, v, u, *parent;
  208. int *dist;
  209. struct minHeap *min_heap = createMinHeap(V);
  210. struct minHeapNode *min_heap_node;
  211. struct listNode *pNode;
  212.  
  213. dist = (int*)malloc(sizeof(int)*V);
  214. parent = (int*)malloc(sizeof(int)*V);
  215.  
  216. for(v = 0; v < V; ++v)
  217. {
  218. parent[0] = -1;
  219. dist[v] = BIGNMB;
  220. min_heap->array[v] = newMinHeapNode(v, dist[v]);
  221. min_heap->pos[v] = v;
  222. }
  223.  
  224. min_heap->array[src] = newMinHeapNode(src, dist[src]);
  225. min_heap->pos[src] = src;
  226. dist[src] = 0;
  227. decrease(min_heap, src, dist[src]);
  228.  
  229. min_heap->size = V;
  230.  
  231. while(!isEmpty(min_heap))
  232. {
  233. min_heap_node = takeMin(min_heap);
  234. u = min_heap_node->v;
  235.  
  236. pNode = graph->array[u].head;
  237. while(pNode != NULL)
  238. {
  239. v = pNode->dest;
  240. if(isInMinHeap(min_heap, v) && dist[u] != BIGNMB && pNode->weight + dist[u] < dist[v])
  241. {
  242. dist[v] = dist[u] + pNode->weight;
  243. parent[v] = u;
  244. decrease(min_heap, v, dist[v]);
  245. }
  246. if(pNode->pos == drak_pos && drak_z == 0) {
  247. drak_z = 1;
  248. return parent;
  249. }
  250.  
  251. if(pNode->pos == generator_pos)
  252. generator = 1;
  253.  
  254. if((pNode->pos == teleport_pos[0] || pNode->pos == teleport_pos[1] || pNode->pos == teleport_pos[2]) && drak_z == 1 && generator == 1 && teleport == 0)
  255. {
  256. teleport = 1;
  257. teleport_pos[0] = -1;
  258. *cesta = princess_pos[0];
  259. return parent;
  260. }
  261.  
  262. if(pNode->pos == princess_pos[0] && drak_z == 1)
  263. {
  264. *cesta = princess_pos[0];
  265. princess_pos[0] = -1;
  266. return parent;
  267. }
  268.  
  269. if(pNode->pos == princess_pos[1] && drak_z == 1)
  270. {
  271. *cesta = princess_pos[1];
  272. princess_pos[1] = -1;
  273. return parent;
  274. }
  275.  
  276. if(pNode->pos == princess_pos[2] && drak_z == 1)
  277. {
  278. *cesta = princess_pos[2];
  279. princess_pos[2] = -1;
  280. return parent;
  281. }
  282.  
  283. if(pNode->pos == princess_pos[3] && drak_z == 1)
  284. {
  285. *cesta = princess_pos[3];
  286. princess_pos[3] = -1;
  287. return parent;
  288. }
  289.  
  290. if(pNode->pos == princess_pos[4] && drak_z == 1)
  291. {
  292. *cesta = princess_pos[4];
  293. princess_pos[4] = -1;
  294. return parent;
  295. }
  296.  
  297. pNode = pNode->next;
  298. }
  299. }
  300. return 0;
  301. }
  302.  
  303. int *zachran_princezne(char **mapa, int n, int m, int t, int *dlzka_cesty)
  304. {
  305. int i, j, poc = 0, *dist, *path, cesta, l, k, *tmp, totalCount = 0, o, pred;
  306. struct Graph* graph = createGraph(n,m);
  307.  
  308. path = (int*)malloc(sizeof(int)*n*m);
  309. tmp = (int*)malloc(sizeof(int)*n*m);
  310.  
  311. for(i=0;i<n;i++)
  312. {
  313. for(j=0;j<m;j++)
  314. {
  315.  
  316. if(mapa[i][j] == 'D')
  317. drak_pos = poc;
  318.  
  319. if(mapa[i][j] == 'P')
  320. {
  321. princess_pos[princess_count] = poc;
  322. princess_count++;
  323. }
  324.  
  325. if(mapa[i][j] == 'G')
  326. generator_pos = poc;
  327.  
  328. if(mapa[i][j] == '0')
  329. {
  330. teleport_pos[teleport_count] = poc;
  331. teleport_count++;
  332. }
  333.  
  334. if(j==0 && i==0)
  335. {
  336. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  337. addEdge(graph, poc, poc+m, getWeight(mapa[i][j]));
  338. poc++;
  339. }
  340. else if(j!=0 && i==0 && j != m-1)
  341. {
  342. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  343. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  344. addEdge(graph, poc, poc+m, getWeight(mapa[i][j]));
  345. poc++;
  346. }
  347. else if(j==m-1 && i==0)
  348. {
  349. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  350. addEdge(graph, poc, poc+m, getWeight(mapa[i][j]));
  351. poc++;
  352. }
  353. else if(j==0 && i==n-1)
  354. {
  355. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  356. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  357. poc++;
  358. }
  359. else if(j!=0 && i==n-1 && j!=m-1)
  360. {
  361. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  362. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  363. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  364. poc++;
  365. }
  366. else if(j==m-1 && i==n-1)
  367. {
  368. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  369. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  370. poc++;
  371. }
  372. else if(j==0 && i!=0 && i!=n-1)
  373. {
  374. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  375. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  376. addEdge(graph, poc, poc+m, getWeight(mapa[i][j]));
  377. poc++;
  378. }
  379. else if(j==m-1 && i!=0 && i!=n-1)
  380. {
  381. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  382. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  383. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  384. poc++;
  385. }
  386. else if(j!=0 && i!=0 && i!=n-1 && j!= m-1)
  387. {
  388. addEdge(graph, poc, poc-m, getWeight(mapa[i][j]));
  389. addEdge(graph, poc, poc-1, getWeight(mapa[i][j]));
  390. addEdge(graph, poc, poc+m, getWeight(mapa[i][j]));
  391. addEdge(graph, poc, poc+1, getWeight(mapa[i][j]));
  392. poc++;
  393. }
  394. }
  395. }
  396.  
  397. dist = dijkstra(graph, 0, &cesta, m);
  398. path[0] = 0;
  399. path[1] = 0;
  400. k = drak_pos;
  401. i=1;
  402. while(1)
  403. {
  404. tmp[i] = k;
  405. i++;
  406. k = dist[k];
  407. totalCount++;
  408. if(k==0)
  409. break;
  410. }
  411.  
  412. l = totalCount;
  413. for (i = 1; i <= totalCount; i++){
  414. path[i*2] = tmp[l] % m;
  415. path[i*2+1] = tmp[l] / m;
  416. l--;
  417. }
  418.  
  419. for(j=0;j<princess_count;j++)
  420. {
  421. if(j==0)
  422. {
  423. dist = dijkstra(graph, drak_pos, &cesta, m);
  424. k = cesta;
  425. pred = drak_pos;
  426. }
  427. else
  428. {
  429. dist = dijkstra(graph, pred, &cesta, m);
  430. k = cesta;
  431. }
  432. if(cesta != -1) {
  433. i=0;
  434. while(1)
  435. {
  436. tmp[i] = k;
  437. i++;
  438. k = dist[k];
  439. totalCount++;
  440. if(j==0) {
  441. if(k==drak_pos)
  442. break;
  443. }
  444. else
  445. {
  446. if(k==pred)
  447. break;
  448. }
  449. }
  450.  
  451. l = i-1;
  452. for (o = totalCount-i+1; o <= totalCount; o++){
  453. path[o*2] = tmp[l] % m;
  454. path[o*2+1] = tmp[l] / m;
  455. l--;
  456. }
  457. pred = cesta;
  458. }
  459. else
  460. {
  461. k = 8;
  462. i=0;
  463. while(1)
  464. {
  465. tmp[i] = k;
  466. i++;
  467. k = dist[k];
  468. totalCount++;
  469. if(j==0) {
  470. if(k==drak_pos)
  471. break;
  472. }
  473. else
  474. {
  475. if(k==pred)
  476. break;
  477. }
  478. }
  479.  
  480. l = i-1;
  481. for (o = totalCount-i+1; o <= totalCount; o++){
  482. path[o*2] = tmp[l] % m;
  483. path[o*2+1] = tmp[l] / m;
  484. l--;
  485. }
  486. }
  487. }
  488.  
  489. if(teleport == 1) {
  490. dist = dijkstra(graph, 35, &cesta, m);
  491. k = cesta;
  492. i=0;
  493. while(1)
  494. {
  495. tmp[i] = k;
  496. i++;
  497. k = dist[k];
  498. totalCount++;
  499. if(k==35)
  500. break;
  501. }
  502. tmp[i] = 35;
  503. i++;
  504. totalCount++;
  505. l = i-1;
  506. for (i = totalCount-i+1; i <= totalCount; i++){
  507. path[i*2] = tmp[l] % m;
  508. path[i*2+1] = tmp[l] / m;
  509. l--;
  510. }
  511.  
  512. }
  513. *dlzka_cesty = totalCount+1;
  514.  
  515. return path;
  516. }
  517.  
  518.  
  519. int main()
  520. {
  521. int dlzka_cesty, i, *path;
  522. char **mapa;
  523. mapa = (char**)malloc(7*sizeof(char*));
  524.  
  525.  
  526. for(i=0;i<7;i++)
  527. mapa[i] = (char*)malloc(sizeof(char) * 7);
  528.  
  529. mapa[0] = "HGHPCDC";
  530. mapa[1] = "C0CCHPP";
  531. mapa[2] = "HHHHHCH";
  532. mapa[3] = "HHHHHHC";
  533. mapa[4] = "0CCCHCH";
  534. mapa[5] = "0CHCH1C";
  535. mapa[6] = "CPCCCHH";
  536.  
  537.  
  538. path = zachran_princezne(mapa, 7, 7, 100, &dlzka_cesty);
  539.  
  540. for (i=0;i<dlzka_cesty;++i)
  541. printf("%d %d\n", path[i*2], path[i*2+1]);
  542.  
  543. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement