Cod sursa(job #2225914)

Utilizator mgntMarius B mgnt Data 28 iulie 2018 17:13:59
Problema Copii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 31.46 kb
                                                                             
#define FOLD__SCOPE                                                          
                                                                             
#ifdef  FOLD__SCOPE  /// includes                                            
                                                                             
#include <cstddef>                                                           
#include <fstream>                                                           
#include <sstream>                                                           
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// typedefs                                            
                                                                             
typedef  ::std::size_t  stsz;                                                
                                                                             
stsz  const one_v = 1;                                                       
stsz  const max_n = 10;                                                      
stsz  const max_s = (one_v << max_n);                                        
                                                                             
typedef  ::std::string  stsg;                                                
                                                                             
typedef  ::std::stringstream  stss;                                          
typedef  ::std::ifstream      stis;                                          
typedef  ::std::ofstream      stos;                                          
                                                                             
typedef  stsz  ardn[max_n];                                                  
typedef  stsz  ards[max_s];                                                  
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// min bit                                             
                                                                             
stsz                                                                         
inline                                                                       
min_bit                                                                      
(                                                                            
  stsz  S                                                                    
)                                                                            
{                                                                            
  return ((1+(S ^ (S-1)))>>1);                                               
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// context                                             
                                                                             
struct ctxt                                                                  
{                                                                            
  stsz  n;                                                                   
  ardn  A;                                                                   
  ardn  T;                                                                   
  ards  F;                                                                   
  stsz  k;                                                                   
                                                                             
  ctxt                                                                       
  ()                                                                         
  noexcept                                                                   
  {                                                                          
    n = 0;                                                                   
                                                                             
    stsz  i = 0;                                                             
                                                                             
    for (i = 0; max_n > i; ++ i  )                                           
    {                                                                        
      A[i] = 0;                                                              
    }                                                                        
                                                                             
    for (i = 0; max_n > i; ++ i  )                                           
    {                                                                        
      T[i] = 0;                                                              
    }                                                                        
                                                                             
    for (i = 0; max_s > i; ++ i  )                                           
    {                                                                        
      F[i] = 0;                                                              
    }                                                                        
                                                                             
    k = 0;                                                                   
                                                                             
  }                                                                          
                                                                             
}                                                                            
;                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// input                                               
                                                                             
bool                                                                         
read_input                                                                   
(                                                                            
  ctxt  & x                                                                  
)                                                                            
{                                                                            
  ardn  A;                                                                   
                                                                             
  stsz  i = 0;                                                               
                                                                             
  for (i = 0; max_n > i; ++ i  )                                             
  {                                                                          
    A[i] = 0;                                                                
  }                                                                          
                                                                             
  stss  ss;                                                                  
  stis  is("copii.in");                                                      
  stsg  il;                                                                  
                                                                             
                                                                             
  stsz  n = 0;                                                               
                                                                             
  getline(is, il);                                                           
  ss << il << '\n';                                                          
                                                                             
  ss >> n;                                                                   
                                                                             
  bool  ok = false;                                                          
                                                                             
  ok = ( (1 <= n ) && (max_n >= n)  );                                       
                                                                             
  if ( ! ok  )                                                               
  {                                                                          
    /// Invalid input.                                                       
    return false;                                                            
  }                                                                          
                                                                             
  stsz  j = 0;                                                               
  stsz  a = 0;                                                               
  stsz  p = 1;                                                               
                                                                             
  for (i = 0; n > i; ++ i  )                                                 
  {                                                                          
    getline(is, il);                                                         
                                                                             
    ok = (n <= il.size()  );                                                 
                                                                             
    if ( ! ok  )                                                             
    {                                                                        
      /// Invalid input.                                                     
      return false;                                                          
    }                                                                        
                                                                             
    a = 0;                                                                   
    p = 1;                                                                   
                                                                             
    for (j = 0; n > j; ++ j  )                                               
    {                                                                        
      ok = (  ( '0' == (il[j]) ) || ( '1' == (il[j]) )  );                   
                                                                             
      if ( ! ok  )                                                           
      {                                                                      
        /// Invalid input.                                                   
        return false;                                                        
      }                                                                      
                                                                             
      a = ( ('1' == (il[j]) ) ? (a + p) : a  );                              
      p = p + p;                                                             
                                                                             
    }                                                                        
                                                                             
    A[i] = a;                                                                
                                                                             
  }                                                                          
                                                                             
                                                                             
  /// Success!                                                               
                                                                             
  x.n = n;                                                                   
                                                                             
  for ( i = 0; n > i; ++ i  )                                                
  {                                                                          
    x.A[i] = A[i];                                                           
  }                                                                          
                                                                             
  return true;                                                               
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// friends                                             
                                                                             
void                                                                         
compute_friends                                                              
(                                                                            
  ctxt  & x                                                                  
)                                                                            
{                                                                            
  stsz  const n = x.n;                                                       
                                                                             
  stsz  const B = (1 << n);                                                  
                                                                             
                                                                             
  ardn  & A = x.A;                                                           
  ards  & F = x.F;                                                           
                                                                             
  F[0] = 0;                                                                  
                                                                             
  stsz  S = 1;                                                               
  stsz  M = 0;                                                               
  stsz  b = 1;                                                               
  stsz  i = 0;                                                               
                                                                             
  for (S = 1; B > S; ++S)                                                    
  {                                                                          
    b = min_bit(S);                                                          
    M = S ^ b;                                                               
                                                                             
    if (0 != M)                                                              
    {                                                                        
      F[S] = F[M] | F[b];                                                    
    }                                                                        
    else                                                                     
    {                                                                        
      F[S] = A[i];                                                           
      i    = 1 + i;                                                          
    }                                                                        
                                                                             
  }                                                                          
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// increment                                           
                                                                             
void                                                                         
increment                                                                    
(                                                                            
  ctxt      & x                                                              
, stsz  const h                                                              
)                                                                            
{                                                                            
  ardn  & T = x.T;                                                           
  ards  & F = x.F;                                                           
                                                                             
  stsz  i = 0;                                                               
  stsz  j = 1;                                                               
                                                                             
  for (i = 0; h > i; ++ i  )                                                 
  {                                                                          
    for (j = 1 + i; h > j; ++ j  )                                           
    {                                                                        
      if (  (0 == ( (F[T[i]]) & (T[j]) )  ) ||                               
            (0 == ( (F[T[j]]) & (T[i]) )  )     )                            
      {                                                                      
        return;                                                              
      }                                                                      
                                                                             
    }                                                                        
                                                                             
  }                                                                          
                                                                             
  x.k = 1 + x.k;                                                             
                                                                             
}                                                                            
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// delegate                                            
                                                                             
void                                                                         
delegate                                                                     
( ctxt      & x                                                              
, stsz  const h                                                              
, stsz  const S                                                              
, stsz  const F                                                              
, stsz  const D                                                              
)                                                                            
;                                                                            
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// count                                               
                                                                             
void                                                                         
count                                                                        
( ctxt  & x                                                                  
, stsz    h                                                                  
, stsz    S                                                                  
)                                                                            
{                                                                            
  if (0 == S)                                                                
  {                                                                          
    increment(x, h);                                                         
  }                                                                          
  else                                                                       
  {                                                                          
    stsz  const b = min_bit(S);                                              
                                                                             
    delegate(x, h, S, b, 0);                                                 
                                                                             
  }                                                                          
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// delegate                                            
                                                                             
void                                                                         
delegate                                                                     
( ctxt      & x                                                              
, stsz  const h                                                              
, stsz  const S                                                              
, stsz  const F                                                              
, stsz  const D                                                              
)                                                                            
{                                                                            
  /// F ― fixed                                                              
  /// D ― dropped                                                            
                                                                             
  x.T[h] = F;                                                                
  count(x, 1 + h, S ^ F);                                                    
                                                                             
  stsz  M = (S ^ F) ^ D;                                                     
  stsz  E = D;                                                               
                                                                             
  while (0 != M)                                                             
  {                                                                          
    stsz  const b = min_bit(M);                                              
    delegate(x, h, S, F | b, E);                                             
    E = E | b;                                                               
    M = M ^ b;                                                               
  }                                                                          
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// solve                                               
                                                                             
void                                                                         
solve                                                                        
(                                                                            
  ctxt  & x                                                                  
)                                                                            
{                                                                            
                                                                             
  compute_friends(x);                                                        
                                                                             
  stsz  const n = x.n;                                                       
  stsz  const S = ((1<<n) - 1);                                              
                                                                             
  count(x, 0, S);                                                            
                                                                             
  x.k = x.k - 1;                                                             
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// output                                              
                                                                             
void                                                                         
write_output                                                                 
(                                                                            
  ctxt const  & x                                                            
)                                                                            
{                                                                            
  stsz  answer = x.k;                                                        
                                                                             
  stos  os ("copii.out");                                                    
  os << answer << '\n';                                                      
                                                                             
}                                                                            
                                                                             
                                                                             
#endif                                                                       
#ifdef  FOLD__SCOPE  /// demo                                                
                                                                             
bool                                                                         
demo                                                                         
()                                                                           
{                                                                            
  ctxt  x;                                                                   
                                                                             
  bool  const ok = read_input(x);                                            
                                                                             
  if ( ! ok  )                                                               
  {                                                                          
    return false;                                                            
  }                                                                          
                                                                             
  solve(x);                                                                  
  write_output(x);                                                           
                                                                             
  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