Hezov

Defrag OJI IX 2015

May 17th, 2024
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.36 KB | Source Code | 0 0
  1. #include <fstream>
  2. using namespace std;
  3. ifstream cin("defrag.in");
  4. ofstream cout("defrag.out");
  5. ///Disk fiind declarat global are toate valorile 0.
  6. int disk[101][361]; ///disk[pista][sector].
  7. //Un cluster este o pozitie a unui punct A(x,y) de pe disk.
  8. int cerinta , pista , sector;
  9. int cluster, x , y;
  10.  
  11. //Functia "mutari" returneaza minimul de mutari pt defragmentare.
  12. //Ideea pentru minimul de mutari este explicata in main.
  13. int mutari(int i)
  14. {
  15.     int nr1 = disk[i][sector];
  16.     int sol = 0;
  17.     ///Caz particular -  pista este libera.
  18.     if(nr1 == 0)
  19.         return 0; //Nu incheie programul ci returneaza valoarea 0.
  20.     ///Sa luam fiecare interval [p,j] care contine nr1 pozitii.
  21.     int j , p , interval;
  22.     for(j = nr1;j<=sector;j++)
  23.     {
  24.         p = j - nr1;
  25.         interval = disk[i][j] - disk[i][p];
  26.         //cout<<interval<<' ';
  27.         if(interval > sol)
  28.             sol = interval;
  29.     }
  30.     //cout<<'\n';
  31.     /**Codul este bun , exemplul da cum trebuie dar daca trimitem
  32.     ce am facut pana acum, primim 40 de puncte. DE CE??  */
  33.  
  34.     /**O pista este circulara. Sa luam un exemplu pe o pista:
  35.      pista{1,1,0,0,1,1} . nr1 = 4.
  36.      poz   1 2 3 4 5 6
  37.                p     j (interval final)
  38.      Observati ca daca pista este circulara asta inseamna ca
  39.      inceputul (poz: 1) si sfarsitul(poz: 6) sunt una langa alta.
  40.      Cand noi cautam pe intervale de cate 4 numere, nu trecem
  41.      si prin intervalul compus din pozitiile {5,6,1,2}
  42.      care contine de fapt numarul maxim cautat (4). Adica nu este nevoie de mutari
  43.      Pentru a repara aceasta neatentie putem :
  44.      - dupa cum a sugerat Vlad  sa dublam efectiv vectorul si sa parcurgem de doua ori.
  45.      - dupa cum am sugerat eu , sa facem un artificiu de calcul pentru a parcurge doar
  46.      intervalele neverificate. In continuare voi explica ideea mea.
  47.     */
  48.  
  49.     /** Sa luam exemplul de mai devreme doar ca dublat:
  50.         pista{1,1,0,0,1,1,1,1,0, 0, 1, 1} . nr1 = 4 + 4.
  51.         poz   1 2 3 4 5 6 7 8 9 10 11 12
  52.                   p     j                 prima pereche (p,j)este ultimul interval din primul exemplu
  53.                               p        j  a doua este ultimul interval din exemplul dublat.
  54.                         p     j           a treia este de fapt ultimul interval care ne intereseaza.
  55.  
  56.         dupa ce (j > sector) putem calcula suma partiala din pozitia j in urmatorul mod :
  57.         s = disk[i][sector]+disk[i][j-sector].
  58.         Putem astfel sa parcurgem restul intervalelor pana cand p = sector;
  59.     */
  60.     for(p = sector - nr1 + 1, j = sector+1; p <= sector; p++ ,j++)
  61.     {
  62.         interval = disk[i][sector] + disk[i][j-sector] - disk[i][p];
  63.         if(interval > sol)
  64.             sol = interval;
  65.     }
  66.     return nr1 - sol;
  67. }
  68.  
  69.  
  70.  
  71. //Functie ce afiseaza diskul.(Pentru intelegere)
  72. void afisareDisk()
  73. {       cout<<'\n';
  74.      for(int i = 1;i<=pista;i++){
  75.         for(int j = 1;j<=sector;j++)
  76.             cout<<disk[i][j]<<' ';
  77.         cout<<'\n';}
  78. }
  79. int main()
  80. {
  81.     cin >> cerinta >> pista >> sector;
  82.     cin >> cluster;
  83.     for(int i = 1; i <= cluster;i++)
  84.     {
  85.         cin >> x >> y;
  86.         disk[x][y] = 1;
  87.     }
  88.     //afisareDisk();
  89.  
  90.     ///Facem suma partiala pe fiecare pista in parte.
  91.     for(int i = 1;i<=pista;i++)
  92.         for(int j = 1;j<=sector;j++)
  93.             disk[i][j]+=disk[i][j-1];
  94.  
  95.     //afisareDisk();
  96.  
  97.     if(cerinta == 1)
  98.     {
  99.         /**Suma partiala fiind facuta, elementul disk[i][sector]
  100.         contine cate clustere sunt ocupate pe pista i.
  101.         Numaram cate dintre acestea sunt 0 (libere) pt prima cerinta.*/
  102.         int sol = 0;
  103.         for(int i = 1; i <= pista; i++)
  104.             if(disk[i][sector] == 0)
  105.                 sol++;
  106.         cout << sol;
  107.         return 0;
  108.         //"return 0;" incheie programul.
  109.     }
  110.     if(cerinta == 2)
  111.     {
  112.         /** Fie - nr1 numarul de clustere de pe o pista.
  113.                 - sol numarul maxim de clustere dintr-un interval de nr1 numere
  114.             Numarul minim de mutari: nr1 - sol.
  115.  
  116.             Putem calcula cate clustere sunt intr-un interval [i,j]
  117.             in O(1)datorita sumelor partiale.
  118.             Nr clustere de pe linia i din intervalul [p,j] =
  119.             disk[i][j] - disk[i][j-p].  */
  120.         ///Afisam numarul minim de mutari de pe fiecare pista.
  121.         for(int i = 1; i <= pista; i++)
  122.             cout<<mutari(i)<<' ';
  123.     }
  124.     return 0;
  125. }
Add Comment
Please, Sign In to add comment