Cod sursa(job #2253307)

Utilizator gabrielmGabriel Majeri gabrielm Data 3 octombrie 2018 21:09:11
Problema Transport Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2 kb
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>

int v[16384];
int n, k;

// Verifica daca un anumit volum al camionului este suficient.
bool verif_volum(int vol) {
  // Parcurgem stiva, incercam sa umplem camionul intr-un mod greedy.
  // Cand nu mai e loc, facem un alt drum.

  int nr_drumuri = 1;
  int incarcatura = 0;

  // Trebuie transportate toate saltelele
  for (int i = 0; i < n; ++i) {
    int saltea = v[i];

    // Mai este loc
    if (incarcatura + saltea <= vol) {
      incarcatura += saltea;
    } else {
      // Inca un drum
      ++nr_drumuri;
      incarcatura = saltea;

      // Am depasit limita
      if (nr_drumuri > k) {
	      return false;
      }
    }
  }

  // Am transportat tot
  return true;
}

// Volumul minim gasit pana acum pentru camion.
int raspuns = 0;

// Cauta binar cel mai mic volum posibil pentru un camion
// care poate efectua cele K transporturi.
void cauta(int st, int dr) {
  int mid = st + (dr - st) / 2;

  if (st > dr) {
    return;
  }

  // Vedem daca volumul este suficient
  bool ok = verif_volum(mid);

  if (ok) {
    // Am gasit un volum acceptabil
    raspuns = mid;

    // Daca este posibil, incercam sa minimizam volumul
    cauta(st, mid - 1);
  } else {
    // Daca nu, trebuie sa folosim un volum mai mare
    cauta(mid + 1, dr);
  }
}

int main(void) {
  FILE* fin = fopen("transport.in", "r");
  FILE* fout = fopen("transport.out", "w");

  // Citim datele
  fscanf(fin, "%d %d", &n, &k);

  // Daca am lua toate saltelele intr-un transport,
  // am avea nevoie de cel mult suma volumelor:
  int suma = 0;

  // Avem nevoie de destul volum in camion pentru
  // cea mai mare saltea:
  int max = 0;

  for (int i = 0; i < n; ++i) {
    int saltea = 0;
    fscanf(fin, "%d", &saltea);

    suma += saltea;

    if (saltea > max) {
      max = saltea;
    }

    v[i] = saltea;
  }

  // Caut binar volumul minim
  cauta(max, suma);

  // Afisare
  fprintf(fout, "%d\n", raspuns);

  // Clean up
  fclose(fin);
  fclose(fout);
}