Cod sursa(job #1033122)

Utilizator krissu93FMI Tiugan Cristiana Elena krissu93 Data 16 noiembrie 2013 14:47:51
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <iostream>
#include <fstream>
#include <utility>
#include <algorithm>

using namespace std;

const int kMax = 101;

int numar_pers, lapte_min, timp_max;
pair< int, pair<int, int> > timp[kMax];
pair<int, int> timp_fol[kMax];
pair<int, int> aux[kMax];

void getData(){
  ifstream in("lapte.in");
  in>>numar_pers;
  in>>lapte_min;
  for (int counter = 1; counter<=numar_pers; ++counter) {
    int A, B;
    in>>A>>B;
    timp_max = max(A, timp_max);
    timp_max = max(B, timp_max);
    timp[counter].first = counter;
    timp[counter].second = pair<int, int>(A,B);
  }
  in.close();
}

void putData(){
  for(int i=1; i<=numar_pers;++i)
    cout<<timp[i].first<<" "<<timp[i].second.first<<" "<<timp[i].second.second<<"\n";
}

bool compara(const pair<int,pair<int, int> >& A, const pair<int,pair<int, int> >& B) {
   // cout<<2<<"\n";
  if (A.second.first * B.second.second != B.second.first * A.second.second)
    return A.second.first * B.second.second != B.second.first * A.second.second;
  else
    return A.second.first<B.second.first;
}

bool compara2(const pair<int,pair<int, int> >& A, const pair<int,pair<int, int> >& B) {
  return A.first < B.first;
}

void init(){
  for(int i = 1; i<=numar_pers; ++i)
    aux[i].first = aux[i].second = 0;

}

void update(){
  for (int i = 1; i<=numar_pers; ++i)
    timp_fol[i] = aux[i];
}

bool verifica(int T){
  init();
  int suma = 0;
  for (int i = 1; i <= numar_pers && suma < lapte_min; ++i){
    aux[i].first = min(lapte_min-suma, T/timp[i].second.first);
    suma += aux[i].first;
  }
  if (suma < lapte_min) return false; // am terminat persoanele si nu am terminat laptele

  suma = 0;
  for (int i = numar_pers; i>=1 ; --i){
    aux[i].second = min(lapte_min-suma, T/ timp[i].second.second);
    suma += aux[i].second;
  }
  if (suma < lapte_min) return false;

  //pentru cei care vor bea din ambele tipuri de lapte, avem grija sa nu depaseasca timpul
  for (int i = 1; i <= numar_pers; ++i)
    if (aux[i].first * timp[i].second.first + aux[i].second * timp[i].second.second > T) return false;

  return true;
}



int cauta(int st, int dr){
  int mijloc = (st+dr)/2;
  int minim = timp_max;
  while (st<=dr) {
    bool ok = verifica(mijloc);
    if (ok == true){
      minim = mijloc;
      update();
      dr = mijloc - 1;
      mijloc = (st+dr)/2;
    }else {
      st = mijloc + 1;
      mijloc = (st+dr)/2;
      }
  }
  return minim;
}
int solve(){
  sort(timp+1, timp+numar_pers+1, compara);
  cout<<"\n";
  putData();
  timp_max = timp_max * lapte_min;
  int a = cauta(1, timp_max);
  return a;
}
int main(){
  getData();
  putData();
  timp_max++;
  ofstream out("lapte.out");
  out<<solve()<<"\n";

  sort(timp+1, timp+numar_pers+1,compara2);
  for (int i = 1; i<=numar_pers; ++i)
    out<<timp_fol[timp[i].first].first<<" "<<timp_fol[timp[i].first].second<<"\n";
  out.close();
  return 0;

}