Cod sursa(job #2223974)

Utilizator mgntMarius B mgnt Data 22 iulie 2018 13:12:51
Problema Heavy metal Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 20.99 kb
                                                                             
#define FOLD__SCOPE                                                          
                                                                             
#ifdef  FOLD__SCOPE   /// includes                                           
                                                                             
#include <fstream>                                                           
#include <vector>                                                            
#include <limits>                                                            
#include <algorithm>                                                         
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// typedefs                                           
                                                                             
typedef  ::std::size_t  stsz;                                                
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// birt                                               
                                                                             
/// birt ― [B] components [i]ncreasing st[r]uc[t]                            
                                                                             
struct birt                                                                  
{                                                                            
  stsz  A;                                                                   
  stsz  B;                                                                   
  stsz  I;                                                                   
  stsz  X;                                                                   
  stsz  M;                                                                   
                                                                             
  birt() noexcept : A(0), B(0), I(0), X(0), M(0) { }                         
};                                                                           
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// comparator                                         
                                                                             
/// Comparator for sorting the C sequence increasingly by ending times.      
                                                                             
bool                                                                         
increasinglyByEndingTimes                                                    
(                                                                            
  birt const  & u                                                            
, birt const  & v                                                            
)                                                                            
noexcept                                                                     
{                                                                            
  return u.B < v.B;                                                          
}                                                                            
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// airt                                               
                                                                             
/// airt ― [A] components [i]ncreasing s[t]ruc[t]                            
                                                                             
struct airt                                                                  
{                                                                            
  stsz  A;                                                                   
  stsz  I;                                                                   
                                                                             
  airt () noexcept : A(0), I(0) { }                                          
                                                                             
};                                                                           
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// comparator                                         
                                                                             
/// Comparator for sorting the D vector increasingly by starting times.      
                                                                             
bool                                                                         
increasinglyByStartingTimes                                                  
(                                                                            
  airt const  & u                                                            
, airt const  & v                                                            
)                                                                            
noexcept                                                                     
{                                                                            
  return u.A < v.A;                                                          
}                                                                            
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// typedefs                                           
                                                                             
typedef  ::std::vector < birt >  vtbi;                                       
typedef  ::std::vector < airt >  vtai;                                       
                                                                             
typedef  ::std::ifstream  stis;                                              
typedef  ::std::ofstream  stos;                                              
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// demo                                               
                                                                             
bool                                                                         
demo                                                                         
()                                                                           
{                                                                            
  #ifdef  FOLD__SCOPE /// state                                              
                                                                             
  vtbi  C;                                                                   
  vtai  D;                                                                   
                                                                             
  #endif                                                                     
  if (true) {         /// read                                               
                                                                             
    /// Verify implementation limits.                                        
    /// Read the input.                                                      
    /// Validate it.                                                         
    /// Aquire space.                                                        
    /// Fail fast.                                                           
                                                                             
    stsz  const max_s = ::std::numeric_limits < stsz > :: max (  ) ;         
                                                                             
    stsz  const min_n = 1;                                                   
    stsz  const max_n = 100000;                                              
                                                                             
    stsz  const min_t = 1;                                                   
    stsz  const max_t = 1000000000;                                          
                                                                             
    bool  ok = false;                                                        
                                                                             
    ok = ( (1 == min_n) && (min_n <= max_n) &&                               
           (max_n == 100000) && (100000 <= max_s) &&                         
           (1 == min_t) && (min_t <= max_t) &&                               
           (max_t == 1000000000) && (1000000000 <= max_s)  );                
                                                                             
    if ( ! ok  )                                                             
    {                                                                        
      /// Implementation limits.                                             
      return false;                                                          
    }                                                                        
                                                                             
    stis  is ("heavymetal.in");                                              
                                                                             
    stsz  n;                                                                 
    is >> n;                                                                 
                                                                             
    ok = ( (min_n <= n) && (max_n >= n)  );                                  
                                                                             
    if ( ! ok  )                                                             
    {                                                                        
      /// Invalid input.                                                     
      return false;                                                          
    }                                                                        
                                                                             
    vtbi  c(n);                                                              
    vtai  d(n);                                                              
                                                                             
    stsz  i = 0;                                                             
    stsz  a = 0;                                                             
    stsz  b = 0;                                                             
                                                                             
    for ( i = 0; n > i; ++ i  )                                              
    {                                                                        
      is >> a >> b;                                                          
                                                                             
      ok = ( (min_t <= a) && (a < b) && (max_t >= b)  );                     
                                                                             
      if ( ! ok  )                                                           
      {                                                                      
        /// Invalid input.                                                   
        return false;                                                        
      }                                                                      
                                                                             
      c[i].A = a;                                                            
      c[i].B = b;                                                            
                                                                             
    }                                                                        
                                                                             
    /// So far so good.                                                      
    C.swap(c);                                                               
    D.swap(d);                                                               
                                                                             
  }                                                                          
  if (true) {         /// solve                                              
                                                                             
    /// Solve problem instance.                                              
                                                                             
    if (true) {  /// Sort the concerts increasingly by their ending times.   
                                                                             
      ::std::sort(C.begin(), C.end(), increasinglyByEndingTimes);            
                                                                             
    }                                                                        
    if (true) {  /// Sort the concerts increasingly by their starting times. 
                                                                             
      stsz  const n = C.size();                                              
                                                                             
      stsz  i = 0;                                                           
                                                                             
      for (i = 0; n > i; ++ i  )                                             
      {                                                                      
        D[i].A = C[i].A;                                                     
        D[i].I = i;                                                          
      }                                                                      
                                                                             
      ::std::sort(D.begin(), D.end(), increasinglyByStartingTimes);          
                                                                             
    }                                                                        
    if (true) {  /// Link each concert to the closest preceding concert.     
                                                                             
      stsz  const n = C.size();  stsz  i = 0;  stsz  j = 0;                  
                                                                             
      for ( j = 0; n > j; ++ j  )                                            
      {                                                                      
                                                                             
        while (C[i].B <= D[j].A)                                             
        {                                                                    
          ++ i;                                                              
        }                                                                    
                                                                             
        C[D[j].I].I = i;                                                     
                                                                             
      }                                                                      
                                                                             
    }                                                                        
    if (true) {  /// Dynamic programming for the win!                        
                                                                             
      /// Bestⱼ ← (Bⱼ − Aⱼ) + max i←0…n−1, Bᵢ ≤ Aⱼ ∷ Bestᵢ,                  
      /// and we use that i must be less than j, and the link from j, to     
      /// max i, the link that we have computed in the previous step!        
      ///                                                                    
      /// At step j, C[j].X ← Bestⱼ                                          
      ///            C[j].M ← max i ← 0…j ∷ Bestⱼ.                           
                                                                             
      stsz  const n = C.size();                                              
                                                                             
      stsz  j = 0;  stsz  i = 0;  stsz  b = 0;  stsz  a = 0;                 
                                  stsz  x = 0;  stsz  m = 0;                 
                                                                             
      for (j = 0; n > j; ++ j)                                               
      {                                                                      
        i = C[j].I;  b = C[j].B;  a = C[j].A;                                
        x = (b - a) + ( (0 < i) ? (C[i-1].M) : 0  );                         
        m = (0 < j) ? ( ::std::max(x, C[j-1].M) ) : x;                       
        C[j].X = x; C[j].M = m;                                              
      }                                                                      
                                                                             
    }                                                                        
                                                                             
  }                                                                          
  if (true) {         /// write                                              
                                                                             
    stsz  const n = C.size();                                                
    stsz  const z = C[n-1].M;                                                
                                                                             
    stos  os("heavymetal.out");                                              
    os << z << '\n';                                                         
                                                                             
  }                                                                          
                                                                             
  return true;                                                               
}                                                                            
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE   /// main                                               
                                                                             
                                                                             
int                                                                          
main                                                                         
()                                                                           
{                                                                            
  int  status = 2;                                                           
                                                                             
  try                                                                        
  {                                                                          
    bool  const ok = demo();                                                 
    status = ( ok ? 0 : 1 );                                                 
  }                                                                          
  catch ( ... )                                                              
  {                                                                          
    status = 3;                                                              
  }                                                                          
                                                                             
  return status;                                                             
}                                                                            
                                                                             
                                                                             
#endif