Cod sursa(job #2016067)

Utilizator TincaMateiTinca Matei TincaMatei Data 28 august 2017 15:19:24
Problema Transport Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.63 kb
#include <stdio.h>
//#include <iso646.h> dar de ce? poti sa folosesti and, or si alte chestii fara asta.
//                    dar oricum codul e mai citibil daca folosesti &&, ||,etc. Parerea mea
#include <ctype.h>

#define NMAX  16000
//#define SALTEA_MAX 16000
#define SALTEA_MAX 256000000   //!!! capacitatea maxima a unui camion nu este 16.000
                               //!!! poti sa ai 16.000 de saltele si sa tb sa faci asta intr-un singur transport
                               //!!! capacitatea maxima este 16.000 * 16.000 = 256.000.000
//#define INFINIT 9000000
#define INFINIT 256000000      //!!! acelasi lucru ca si mai sus, maximul e 256.000.000

int stiva [ NMAX ] ; // nu ca ar fi mare problema, dar parca sunt cam multe spatii

//!!!nu ai nevoie de min si min2(vezi mai jos), iar de regula e bine sa nu folosesti variabile locale
//int N, K, min, min2 ;

//char testare (int cap ) {
char testare(int cap, int N, int K) { //!!!dam N si K ca parametri
  int i, s, transport ;

  s = 0 ;
  transport = 0 ;

  //for (i = 0 ; i < N and stiva[i] <= cap ; ) {
  i = 0;
  while(i < N && stiva[i] <= cap) { //!!!WTF IS DIS? asa te-a invatat Francu?
      /// Inseram saltele pana cand nu mai incap
    if (s + stiva[i] <= cap ) {
      s += stiva[i] ;
      i++;
    /*else {
      if (s > 0 ) { /// Le transportam
        transport++;
        s = 0 ;
      }
    }*/
    } else if(s > 0) { // exista else if :p
      transport++;
      s = 0;
    }
  }

  if (s <= cap ) { /// Ultimele saltele
    transport++;
    s = 0 ;
  }

  //if (transport <= K and stiva[i] <= cap ) { /// Daca am facut mai putin de k transporturi
  if(transport <= K && i == N)//!!!poti sa treci prin toate saltelele, iar cand verifici la if
                                 //!!!stiva[i] <= cap; i o sa fie egal cu N si o sa ai stiva[N]
                                 //!!!si asa iesi din memorie. Din fericire ai avut noroc.
                                 //!!!ca sa vezi daca ai trecut prin toate saltelele si nu ai vreuna
                                 //!!!mai mare decat capacitate, poti sa vezi daca i == N
                                 //!!!daca nu e respectata conditia, inseamna ca ai iesit din while
                                 //!!!deoarece era o saltea mai mare decat tot camionul
    /*if (cap < min2 ) {
      min = transport ;
      min2 = cap ;
    }*/ //!!!o sa vezi ca mai incolo nu mai e nevoie de aceasta verificare
    //return 1 ; /// In care parte mergem
    return 1; //!!!daca ai functii care iti spun 'da' sau 'nu', foloseste valorile 0 si 1
              //!!!daca ai o variabila egala cu 0, atunci e false
              //!!!altfel se evalueaza true
  //return 2 ;
  return 0;
}

//!!!Nu e bine sa complici lucrurile cu recursivitati inutile, daca ai foarte multe cautari binare,
//!!!recursivitatea o sa iti manance foarte mult timp
/*void caut_bin (int st, int dr ) {
  /// Cautam binar capacitatea
  int pivot ;
  pivot = (st + dr ) / 2 ;
  if (st < dr-1 ) {
    if  (testare(pivot) == 1 )  { /// Testam sa vedem daca e minima
      caut_bin(st, pivot ) ;
    }
    else {
      caut_bin(pivot, dr ) ;
    }
  }
}*/

//int caut_bin(int st, int dr) {
int caut_bin(int st, int dr, int N, int K) { //!!!dam N si K ca parametri
  int mid;
  while(dr - st > 1) { //poti sa faci si st < dr - 1, e acelasi lucru
    mid = (st + dr) / 2;
    if(testare(mid, N, K)) //!!!nu mai trebuie sa pui testare(mid) == 1 sau 2, poti sa pui direct testare, dar asta
                     //!!!doar daca testare returneaza 0 sau 1
                     //!!!don't forget: 0 pentru false si 1 pentru true
      dr = mid;
    else
      st = mid;
  }
  return dr; //!!!testare(st) va da mereu false, iar testare(dr) va da mereu true
             //!!!deci dr va avea raspunsul cerut de problema
}

int main() {

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

  int i, N, K;
  //!!!nu mai ai nevoie de astea
  //min =  INFINIT ;
  //min2 = INFINIT ;

  fscanf (fin, "%d%d", &N, &K ) ;

  //!!!acolade inutile, daca ai un if, while, for, else-if care ruleaza doar o instructiune, nu mai e nevoie de acolade
  for (i = 0 ; i < N ; i++ ) //{
    fscanf (fin, "%d", &stiva[i] ) ;
  //}

  //!!!am facut cautarea binara sa returneze ceva
  //caut_bin(1, SALTEA_MAX + 1 ) ;

  //!!!am scos variabilele min si min2
  //fprintf (fout, "%d", min2 ) ;
  //!!!in functie de ce trebuie sa returnezi, trebuie sa ai grija cum faci cu intervalul
  //!!!aici ce e in st stii ca va fi mereu gresit, iar ce e in dr va fi mereu corect
  //!!!daca incepi cu st == 1, e ca si cum ai zice ca 1 nu e bun, dar poate fi si 1 o solutie
  fprintf(fout, "%d", caut_bin(0, SALTEA_MAX, N, K));
  return 0 ;
}