Cod sursa(job #2929024)

Utilizator ulkevinsam kevin ulkevin Data 24 octombrie 2022 14:27:47
Problema Partitie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

#define LEN  300002
//#define LEN 6


typedef struct {
   int val;
   int poz;
} t_element;


t_element a[LEN] = { {0,0} };
//int p[LEN] = {0};
int solution[LEN] = {0};


/**
 *   Fie fie A un sir: a1 < a2 < a3 < ... < an
 *   Urmatorul algoritm realizeaza o partitie minimina respectand conditia D.
 *   Algoritm:
 *      - P este un sir cu ajutorul caruia punem elemente din A in partitii. Ex:
 *         - marcam ca A[i] este in partitia k punand p[i] = k (i.e. elementul i din A e in paritia k)
 *      - Folosim doi "pointeri" i si j astfel:
 *         - daca A[i] este liber, atunci se deschide o noua partitie "k" pt elementul A[i] (P[i] = k) si
 *           apoi cau tprimul colocatar cu A[i] - adica primul j (i.e. ) a.i: 
 *               -  P[j] este liber 
 *               -  A[j] respecta conditia in raport cu A[i]
 *         - daca A[i] nu este liber atunci caut primul colocatar cu A[i], adica tot primul j (dupa i) a.i
 *               -  P[j] este liber 
 *               -  A[j] respecta conditia in raport cu A[i]
 *            Deci exprimam asta astfel:  P[j] = P[i]
 *     - Dupa ce i parcurge toate valorile de la 1 la n, problema este rezolvata optim.
 */


int main() {

   ifstream cinfile("partitie.in");
   //ofstream coutfile("partitie.out");
   
   int N = 0;
   int D = 0;

   cinfile >> N >> D;

   for (int i = 1; i <= N ; i++) {
        cinfile >> a[i].val;
        a[i].poz = i;
   }

   sort(a + 1, a + N + 1, [](t_element a, t_element b) {
      return a.val  < b.val;
   });

   int part_num = 0;
   
   int j = 2;
   for (int i = 1; i <= N; i++) {
       if (solution[a[i].poz] == 0) {
          // a[i] este liber
          part_num++;
          //p[i] = part_num;

          // inregistreaza in solutia finala
          solution[a[i].poz] = part_num;
       }
       
       // caut primul colocatar cu a[i] care e liber si respecta conditia D in raport cu a[i] 
       // Asa dar, sar peste cei care nu respecta conditia de mai sus(luat || nu respecta D).
       while ((j <= N) && (solution[a[j].poz] > 0 || a[j].val < a[i].val + D)) {
          j++;
       }

       if (j <= N) {
          // a[j] devine colocatar cu a[i]
          // p[j] = p[i];

          // inregistreaza in solutia finala
          solution[a[j].poz] = solution[a[i].poz];
       }
   }


   // display the solution
   // coutfile << part_num << endl;
   // for (int i = 1; i <= N; i++) {
   //    coutfile << solution[i] << endl;
   // }

    FILE * fout = fopen( "partitie.out", "w" );
    fprintf( fout, "%d\n", part_num );
    for ( int i = 1; i <= N; i ++ )
        fprintf( fout, "%d\n", solution[i] );
    fclose( fout );
}