Guest User

Untitled

a guest
Apr 20th, 2018
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. typedef struct{ /* pontok koordinátáit tároló struktúra */
  6.     unsigned int x;
  7.     unsigned int y;
  8. }pont;
  9.  
  10. typedef struct { /* adott házhoz szükséges információt tároló struktúra */
  11.     pont koordinata; /* koordináták */
  12.     int kizaras; /* a legközelebbi ház kereső függvénynél szükséges, hogy ne válasszuk ki ugyanazt */
  13. }haz;
  14.  
  15. typedef struct{ /* adott bázioshoz szükséges információt tároló struktúra */
  16.     pont koordinata; /* koordináták */
  17.     char ajandek[27]; /* a bázishoz legközelebbi család ajándékai */
  18.     unsigned int penz; /* a bázishoz legközelebbi család által beküldött pénz */
  19.     unsigned int OsszTavDij; /* a bázishoz tartozó kiszámlázott távolságdíjak összege */
  20.     double MinTav; /* a bázis és a hozzá legközelebb lévő ház távolsága */
  21. }bazis;
  22.  
  23. typedef struct house{ /* házak listájának eleme */
  24.     haz h; /* házhoz tartozó adatok */
  25.     struct house *next; /* következő házra mutató pointer */
  26. }hazelem,*hazpointer;
  27.  
  28. typedef struct base{ /* bazisok listájának eleme */
  29.     bazis b; /* bázihoz tartozó adatok */
  30.     struct base *next; /* követekező elemre mutató pointer */
  31.     struct house *first; /* ehhez a bázishoz tartozó házak listájára mutató pointer */
  32. }baziselem,*bazispointer;
  33.  
  34. bazispointer BazisBeszuras(bazis newdata,bazispointer head){ /* newdata változó berakása a verembe */
  35.     bazispointer temp=malloc(sizeof(baziselem)); /* allokálás */
  36.     temp->b=newdata; /* adatok berakása */
  37.     temp->b.MinTav=-1; /* szükséges adatok nullázása későbbi feltétel miatt */
  38.     temp->b.OsszTavDij=0; /* szükséges adatok nullázása későbbi feltétel miatt */
  39.     temp->first=NULL; /* szükséges adatok nullázása későbbi feltétel miatt */
  40.     temp->next=head; /* következő elemre irányítás */
  41.     head=temp; /* head frissítése */
  42.     return head;
  43. }
  44.  
  45. bazispointer BazisokVerembe(bazispointer head){ /* bázisok beolvasása és elhelyezése egy veremben */
  46.     FILE* in; /* fájl megnyitásához szükséges pointer */
  47.     bazis newdata; /* ideiglenes változó, amibe kerülnek a beolvasott adatok */
  48.     in = fopen( "C:/BASE.DAT" , "rb" ); /* fájl megnyitása */
  49.     while(fread(&newdata.koordinata.y, sizeof(unsigned int), 1, in) && fread(&newdata.koordinata.x, sizeof(unsigned int), 1, in)){ /* koordináták beolvasása */
  50.         head=BazisBeszuras(newdata,head); /* beolvasott elemek berakása a verembe */
  51.     }
  52.     fclose(in); /* fájl bezárása */
  53.     return head; /* az első elemre mutató pointer visszaadása */
  54. }
  55.  
  56. double tavolsag(pont p1,pont p2){ /* két pont közötti távolság kiszámítása */
  57.     unsigned int s;
  58.     double gyokd;
  59.     unsigned int gyoki;
  60.     if(p1.x<p2.x) { s=p1.x; p1.x=p2.x; p2.x=s; }
  61.     if(p1.y<p2.y) { s=p1.y; p1.y=p2.y; p2.y=s; }
  62.     gyokd=sqrt(((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); /* d(P1,P2)=sqrt((x1-x2)^2 + (y1-y2)^2) */
  63.     gyoki=gyokd;
  64.     if(((gyoki-1)*(gyoki-1))==((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))) return (gyoki-1);
  65.     if((gyoki*gyoki)==((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))) return gyoki;
  66.     return gyokd;
  67. }
  68. bazispointer LegkozelebbiBazis(pont newdata,bazispointer head){ /* egy ponthoz a legközelebbi bázis megkeresése */
  69.     double DistTemp; /* az eddig vizsgált legkisebb távolság */
  70.     bazispointer temp; /* a keresett bázisra mutató pointer */
  71.     if(head){ /* első vizsgálásnál a DistTemp-nek nincs értéke, ezért eddig ehhez a bázishoz lesz a legközelebb */
  72.         DistTemp=tavolsag(newdata,head->b.koordinata); /* a legkisebb távolság frissítése */
  73.         temp=head; /* a keresett bázisra mutató pointer frissítése */
  74.     }
  75.     head=head->next; /* következő bázis */
  76.     while(head){
  77.         if(DistTemp>tavolsag(newdata,head->b.koordinata)){ /* ha közelebb van a vizsgált bázishoz, mint az eddig vizsgáltak közül a legközelebbihez */
  78.             DistTemp=tavolsag(newdata,head->b.koordinata); /* a legkisebb távolság frissítése */
  79.             temp=head; /* a keresett bázisra mutató pointer frissítése */
  80.         }
  81.         head=head->next; /* következő bázis */
  82.     }
  83.     return temp; /* a keresett bázisra mutató pointer visszaadása */
  84. }
  85. hazpointer HazBeszuras(haz newdata,hazpointer head){ /* ház beszúrása a listába */
  86.     hazpointer temp=malloc(sizeof(hazelem)); /* allokálás */
  87.     temp->h=newdata; /* adatok berakása */
  88.     temp->h.kizaras=1; /* később használt feltétel beállítása kezdeti értékre */
  89.     temp->next=head; /* következő elemre irányítás */
  90.     head=temp; /* head frissítése */
  91.     return head; /* head visszaadása */
  92. }
  93.  
  94. void HazakBeolvasasa(bazispointer head){ /* házak bázisokhoz rendelése, majd felfűzése a fésű ágaira */
  95.     FILE* in; /* fájl megnyitásához szükséges pointer */
  96.     haz newdata; /* adatok beolvasására használt változó */
  97.     char karakter; /* adatok beolvasására használt változó */
  98.     bazispointer temp; /* keresett bázisra mutató pointer */
  99.     in = fopen( "C:/GIFT.TXT" , "rt" ); /* fájl megnyitás */
  100.     while(!feof(in)){ /* fájl végét jelző feltétel */
  101.         fscanf(in,"%d %d\n",&newdata.koordinata.y,&newdata.koordinata.x); /* koordináták beolvasása */
  102.         temp=LegkozelebbiBazis(newdata.koordinata,head); /* a házhoz legközelebbi bázis megkeresése */
  103.         temp->first=HazBeszuras(newdata,temp->first); /* ház beszúrása a legközelebbi bázison kialakított verembe */
  104.         if(temp->b.MinTav!=-1){ /* ha volt már ház ebben a veremben */
  105.             if(temp->b.MinTav>tavolsag(newdata.koordinata,temp->b.koordinata)){ /* ha a most beolvasott ház a legközelebbi az eddigiek közül*/
  106.                 int i=0; /* stringen végigfutó változó */
  107.                 temp->b.MinTav=tavolsag(newdata.koordinata,temp->b.koordinata); /* távolság átírása */
  108.                 fscanf(in,"%c",&karakter); /* ajándéklista olvasása karakterenként */
  109.                 while(karakter!='\n'){ /* ajándéklista olvasása karakterenként sortörésig */
  110.                     if(karakter!=' '){ /* ha nem space */
  111.                         temp->b.ajandek[i]=karakter; /* karakter beírása stringbe */
  112.                         i++; /* következő string elem */
  113.                     }
  114.                     fscanf(in,"%c",&karakter); /* következőő karakter */
  115.                 }
  116.                 temp->b.ajandek[i]='\0'; /* a string lezárása */
  117.                 fscanf(in,"%d\n",&temp->b.penz); /* a család által beküldött pénz beolvasása */
  118.             }
  119.             else { /* ha nem a most beolvastott a legközelebbi ház, az adatatok beolvasása használás nélkül */
  120.                 int kuka;
  121.                 fscanf(in,"%c",&karakter);
  122.                 while(karakter!='\n'){
  123.                     fscanf(in,"%c",&karakter);
  124.                 }
  125.                 fscanf(in,"%d\n",&kuka);
  126.             }
  127.         }
  128.         else { /* ha nem volt még ház ebben a veremben */
  129.             int i=0; /* stringen végigfutó változó */
  130.             temp->b.MinTav=tavolsag(newdata.koordinata,temp->b.koordinata); /* mivel még nem volt ház a veremben, ez a ház van jelenleg legközelebb a bázishoz, távolság beírása */
  131.             fscanf(in,"%c",&karakter); /* ajándéklista olvasása karakterenként */
  132.             while(karakter!='\n'){ /* ajándéklista olvasása karakterenként amíg az nem sortörés */
  133.                 if(karakter!=' '){ /* ha a beolvasott karakter nem space */
  134.                     temp->b.ajandek[i]=karakter; /* a karakter stringbe írása */
  135.                     i++; /* következő string elem */
  136.                 }
  137.                 fscanf(in,"%c",&karakter); /* következő karakter */
  138.             }
  139.             temp->b.ajandek[i]='\0'; /* sortörés után a string lezárása */
  140.             fscanf(in,"%d\n",&temp->b.penz); /* család által küldött pénz beírása */
  141.         }
  142.     }
  143.     fclose(in);
  144. }
  145.  
  146. unsigned int TavolsagDijazas(double tavolsag){ /* Távolság (méterben) alapján kiküldött útiköltség */
  147.     unsigned int tavolsagi; /* távolság km-ben intben */
  148.     double tavolsagd; /* távolság km-ben double-ban */
  149.     tavolsagi=tavolsag/1000.0;
  150.     tavolsagd=tavolsagi;
  151.     if(tavolsagd==tavolsag/1000.0) return 2*tavolsagi; /* ha az intbeli távolság egyenlő a doublebelivel (azaz km-ben egész a távolság) akkor a díja 2x a távolság */
  152.     else return 2*(tavolsagi+1); /* ha nem egész a távolság, akkor van +1 megkezdett km */
  153. }
  154.  
  155. hazpointer LegkozelebbiHaz(pont bazis, hazpointer head){ /* egy ponthoz legközelebbi ház megkeresése */
  156.     double DistTemp; /* jelenlegi legrövidebb távolság */
  157.     hazpointer temp=NULL; /* jelenlegi legközelebbi házra mutató pointer, ha nincs ilyen akkor NULL */
  158.     int vege=1;
  159.     while(vege && head){ /* amíg nincs vége a házak listájának */
  160.         if(head->h.kizaras){ /* ha olyan házon vagyunk ahol a kizárási feltétel még 1 */
  161.             DistTemp=tavolsag(bazis,head->h.koordinata); /* távolság átírása */
  162.             temp=head; /* házra mutató pointer átírása */
  163.             vege=0;
  164.         }
  165.         head=head->next; /* ha a kizárási feltétel már 0 (lásd később) akkor következő elem */
  166.     }
  167.     while(head){ /* amíg nem érünk a házak végére */
  168.         if(head->h.kizaras && DistTemp>tavolsag(bazis,head->h.koordinata)){ /* ha olyan háznál vagyunk amit még nem zártunk ki és közelebb van mint az eddigi legközelebbi */
  169.             DistTemp=tavolsag(bazis,head->h.koordinata); /* távolság átírása */
  170.             temp=head; /* házra mutató pointer átírása */
  171.         }
  172.         head=head->next; /* követező ház */
  173.     }
  174.     return temp; /* ha a lista végére értünk, a legközelebbire mutató pointer visszaadása (ha nincs ilyen, akkor NULL) */
  175. }
  176. void BazisOsszTavDij(bazispointer head){ /* bázisokhoz tartozó távolságok miatt kiszámlázott díjak összege*/
  177.     hazpointer TempLegkozelebbi; /* adott házhoz legközelebbi házra mutató pointer */
  178.     pont TempBazis; /* adott ház pontja */
  179.     while(head){ /* ha van még házta bázis */
  180.         TempBazis=head->b.koordinata; /* adott pont a bázis pontja */
  181.         TempLegkozelebbi=LegkozelebbiHaz(TempBazis,head->first); /* bázishoz legközelebbi ház megkeresése (ha nincs akkor NULL) */
  182.         while(TempLegkozelebbi){ /* ha van még vizsgált ház */
  183.             head->b.OsszTavDij+=TavolsagDijazas(tavolsag(TempBazis,TempLegkozelebbi->h.koordinata));
  184.             TempLegkozelebbi->h.kizaras=0; /* kizárási feltétel átírása 0-ra */
  185.             TempBazis=TempLegkozelebbi->h.koordinata; /* vizsgált pont átírása az előzőhöz talált legközelebbi pontra */
  186.             TempLegkozelebbi=LegkozelebbiHaz(TempBazis,head->first); /* az új vizsgált ponthoz legközelebbi pont keresés */
  187.         }
  188.         head=head->next; /* következő bázis */
  189.     }
  190. }
  191.  
  192. void ArakBeolvasasa(unsigned int* arak){ /* árak beolvasása a mainben deklarált tömbbe */
  193.     FILE* in; /* fájl megnyitásához használt pointer */
  194.     int k; /* tömbön végigfutó változó */
  195.     in = fopen("C:/PRICE.DAT" , "rb" ); /* fájl megnyitása */
  196.     for(k=0;k<26;k++){ /* tömbön végigfutó ciklus */
  197.         fread(&(arak[k]),sizeof(unsigned int),1,in); /* ár beolvasása */
  198.     }
  199.     fclose(in); /* fáj bezárása */
  200. }
  201.  
  202. int main(){
  203.     bazispointer bazisok=NULL; /* bázisok vermére mutató pointer */
  204.     bazispointer HaziFeladat; /* a házi feladathoz szükséges bázisra mutató pointer */
  205.     unsigned int arak[26], visszajaro, k; /* árak, házi feladathoz szükséges távolság km-ben intben, visszajáró, ajándéklista stringjén végigfutó változó */
  206.     bazisok=BazisokVerembe(bazisok); /* bázisok beolvasása */
  207.     HazakBeolvasasa(bazisok); /* házak felfűzése a bázisokra */
  208.     BazisOsszTavDij(bazisok); /* bázisokhoz tartozó kiszámlázott díjak összegének kiszámolása */
  209.     ArakBeolvasasa(arak); /* árak beolvasása */
  210.     /* Ellenőrzés kiiratással
  211.     while(bazisok){
  212.     printf("(%d;%d) %lf %d %d %s\n",bazisok->b.koordinata.x,bazisok->b.koordinata.y,bazisok->b.MinTav,bazisok->b.OsszTavDij,bazisok->b.penz,bazisok->b.ajandek);
  213.     while(bazisok->first){
  214.         printf("(%d;%d)\n",bazisok->first->h.koordinata.x,bazisok->first->h.koordinata.y);
  215.         bazisok->first=bazisok->first->next;
  216.     }
  217.     bazisok=bazisok->next;
  218.     }
  219.     return 0;
  220.     */
  221.     HaziFeladat=bazisok; /* keresett bázis beállítása az elsőre */
  222.     bazisok=bazisok->next; /* következő bázis */
  223.     while(bazisok){ /* amíg vannak bázisok */
  224.         if(HaziFeladat->b.OsszTavDij>bazisok->b.OsszTavDij) HaziFeladat=bazisok; /* ha kevesebb díjat számlázott ki a bázis, mint az eddigi legkevesebb akkor a keresett bázis pointerének átírása */
  225.         bazisok=bazisok->next; /* következő bázis */
  226.     }
  227.     visszajaro=HaziFeladat->b.penz; /* a család által küldött összeg beírása */
  228.     visszajaro-=TavolsagDijazas(HaziFeladat->b.MinTav);
  229.     for(k=0;k<26;k++){ /* ajándéklistán végigfutó ciklus */
  230.         switch(HaziFeladat->b.ajandek[k]){ /* a következő betű megállapítása */
  231.             /* ha lehetséges, akkor a visszajáróból az ajándék árának levonása, következő ajándék vizsgálása | ha nem akkor kilépés a ciklusból */
  232.             case 'A': if(visszajaro>arak[0]) visszajaro-=arak[0]; else k+=26; break;
  233.             case 'B': if(visszajaro>arak[1]) visszajaro-=arak[1]; else k+=26; break;
  234.             case 'C': if(visszajaro>arak[2]) visszajaro-=arak[2]; else k+=26; break;
  235.             case 'D': if(visszajaro>arak[3]) visszajaro-=arak[3]; else k+=26; break;
  236.             case 'E': if(visszajaro>arak[4]) visszajaro-=arak[4]; else k+=26; break;
  237.             case 'F': if(visszajaro>arak[5]) visszajaro-=arak[5]; else k+=26; break;
  238.             case 'G': if(visszajaro>arak[6]) visszajaro-=arak[6]; else k+=26; break;
  239.             case 'H': if(visszajaro>arak[7]) visszajaro-=arak[7]; else k+=26; break;
  240.             case 'I': if(visszajaro>arak[8]) visszajaro-=arak[8]; else k+=26; break;
  241.             case 'J': if(visszajaro>arak[9]) visszajaro-=arak[9]; else k+=26; break;
  242.             case 'K': if(visszajaro>arak[10]) visszajaro-=arak[10]; else k+=26; break;
  243.             case 'L': if(visszajaro>arak[11]) visszajaro-=arak[11]; else k+=26; break;
  244.             case 'M': if(visszajaro>arak[12]) visszajaro-=arak[12]; else k+=26; break;
  245.             case 'N': if(visszajaro>arak[13]) visszajaro-=arak[13]; else k+=26; break;
  246.             case 'O': if(visszajaro>arak[14]) visszajaro-=arak[14]; else k+=26; break;
  247.             case 'P': if(visszajaro>arak[15]) visszajaro-=arak[15]; else k+=26; break;
  248.             case 'Q': if(visszajaro>arak[16]) visszajaro-=arak[16]; else k+=26; break;
  249.             case 'R': if(visszajaro>arak[17]) visszajaro-=arak[17]; else k+=26; break;
  250.             case 'S': if(visszajaro>arak[18]) visszajaro-=arak[18]; else k+=26; break;
  251.             case 'T': if(visszajaro>arak[19]) visszajaro-=arak[19]; else k+=26; break;
  252.             case 'U': if(visszajaro>arak[20]) visszajaro-=arak[20]; else k+=26; break;
  253.             case 'V': if(visszajaro>arak[21]) visszajaro-=arak[21]; else k+=26; break;
  254.             case 'W': if(visszajaro>arak[22]) visszajaro-=arak[22]; else k+=26; break;
  255.             case 'X': if(visszajaro>arak[23]) visszajaro-=arak[23]; else k+=26; break;
  256.             case 'Y': if(visszajaro>arak[24]) visszajaro-=arak[24]; else k+=26; break;
  257.             case 'Z': if(visszajaro>arak[25]) visszajaro-=arak[25]; else k+=26; break;
  258.         }
  259.     }
  260.     printf("%d\n",visszajaro); /* a megoldás kiiratása */
  261.     return 0;
  262. }
Add Comment
Please, Sign In to add comment