Cod sursa(job #1325005)

Utilizator mgntMarius B mgnt Data 23 ianuarie 2015 01:27:03
Problema NextSeq Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.06 kb

#include <fstream>
#include <iostream>
#include <memory>

// ___________________________________________________________________________

/// \brief Minimum number of symbols.
::std::size_t  const min_num_symbols = 1;

/// \brief Maximum number of symbols.
::std::size_t  const max_num_symbols = 10000;

/// \brief  Minimum symbol.
::std::size_t  const min_symbol = 0;

/// \brief  Maximum symbol.
::std::size_t  const max_symbol = 10000;

/// \brief  Minimum lengths of sequences.
::std::size_t  const min_len = 1;

/// \brief  Maximum lengths of sequences.
::std::size_t  const max_len = 10000;

/// \brief  Maximum counter value.
::std::size_t  const max_counter = 100;

// ___________________________________________________________________________

/// \brief  Data.
class Data
{ public:
  
  /// \brief  Symbol's compact encoding.
  ::std::size_t  m_E[max_symbol+1];
  
  /// \brief  Sequence A.
  ::std::size_t  m_A[max_len];
  
  /// \brief  Sequence B.
  ::std::size_t  m_B[max_len];
  
}
;

// ___________________________________________________________________________

/// \brief  Computes next sequence.
class Demo
{ public:
  
  /// \brief  does processing.
  static
  bool
  process
  ()
  ;
  
}
;

bool
Demo::
process
()
{ // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Acquire space (memory).
  ::std::auto_ptr < Data >  spacePtr;
  Data  * pSpace = new Data;
  spacePtr.reset(pSpace);
  
  Data  & space = ( *pSpace);
  
  ::std::size_t ( &E)[max_symbol+1] = space.m_E;
  
  ::std::size_t ( &A)[max_len] = space.m_A;
  ::std::size_t ( &B)[max_len] = space.m_B;
  
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Prepare E.
  ::std::size_t  i;
  for(i=min_symbol; max_symbol>=i; ++i)
  { E[i] = 0;
  }
    
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Read input.
  
  ::std::ifstream  is("nextseq.in");
  
  ::std::size_t  numSymbols;
  is >> numSymbols;
  bool  ok;
  ok = ( (min_num_symbols <= numSymbols) && (max_num_symbols >= numSymbols) );
  if( !ok)
  { ::std::cerr << "Invalid input: number of symbols." << ::std::endl;
    return false; // Failure.
  }
  
  ::std::size_t  lenA;
  is >> lenA;
  ok = (     ( min_len <= lenA) && ( max_len >= lenA)  );
  if( !ok)
  { ::std::cerr << "Invalid input: length of sequence A." << ::std::endl;
    return false; // Failure.
  }
  
  ::std::size_t  lenB;
  is >> lenB;
  ok = ( ( lenA <= lenB) && ( max_len >= lenB)  );
  if( !ok)
  { ::std::cerr << "Invalid input: length of sequence B." << ::std::endl;
    return false; // Failure.
  }
  
  ::std::size_t  s;
  for(i=0; numSymbols>i; ++i)
  { is >> s;
    ok = ( (min_symbol <= s) && (max_symbol >=s)  );
    if( !ok)
    { ::std::cerr << "Invalid input: symbol." << ::std::cerr;
      return false; // Failure.
    }
    
    ok = (0 == E[s]);
    if( !ok)
    { ::std::cerr << "Invalid input: duplicated symbol." << ::std::cerr;
      return false; // Failure.
    }
    
    E[s] = 1;
  }
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Intermezzo.
  // Compute encodings for our symbols.
  ::std::size_t  encoding = 1;
  for(i=min_symbol; max_symbol >=i; ++i)
  { if(0 != E[i])
    { E[i] = encoding;
      ++encoding;
    }
  }
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Continue reading input.
  
  for(i=0; lenA > i; ++i)
  { is >> s;
    ok = ( (min_symbol <= s) && (max_symbol >= s) && (0 != E[s])  );
    if( !ok)
    { ::std::cerr << "Invalid input: A[i]." << ::std::cerr;
      return false; // Failure.
    }
    
    A[i] = E[s]-1;
  }
  
  for(i=0; lenB > i; ++i)
  { is >> s;
    ok = ( (min_symbol <= s) && (max_symbol >= s) && (0 != E[s])  );
    if( !ok)
    { ::std::cerr << "Invalid input: A[i]." << ::std::cerr;
      return false; // Failure.
    }
    
    B[i] = E[s]-1;
  }
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Move to next sequence, until the length of the sequence A equals the
  // length of the sequence B.
  
  ::std::size_t  const maxSymbol = (numSymbols - 1);
  
  ::std::size_t  counter = 0;
  while( (counter < max_counter) && (lenA < lenB)  )
  { i = lenA;
    while( (0 < i) && (maxSymbol == A[i-1] )  )
    { --i;
      A[i] = 0;
    }
    
    if(0 == i)
    { A[lenA] = 0;
      ++lenA;
    }
    else
    { ++A[i-1];
    }
    
    ++counter;
  }
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Move to next sequence, until the sequence A becomes the sequence B.
  
  // Rightmost position where A equals B, when A and B are of equal lengths.
  ::std::size_t  rightmost = 0;
  while( (rightmost < lenA) && (A[rightmost] == B[rightmost] )  )
  { ++rightmost;
  }
  
  ok = ( (lenA == rightmost) || (A[rightmost] < B[rightmost])  );
  if( !ok)
  { ::std::cerr << "Invalid input: A > B." << ::std::endl;
    return false; // Failure.
  }
  
  // le ― less than or equal to (A ≤ B)
  bool  le = true;
  while( (rightmost < lenA) && (counter < max_counter)  && le  )
  { i=lenA;
    while( (0<i) && (maxSymbol==A[i-1])  )
    { --i;
      A[i] = 0;
    }
    
    if(0 < i)
    { --i;
      ++A[i];
      ++counter;
      if(rightmost == i)
      { while( (rightmost < lenA) && (A[rightmost] == B[rightmost])  )
        { ++rightmost;
        }
      }
    }
    else
    { le = false;
    }
  }
  
  // ☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼☼
  // Write answer, if any.
  
  ok = (rightmost == lenA);
  if( !ok)
  { ::std::cerr << "Invalid input: too many moves." << ::std::endl;
    return false; // Failure.
  }
  
  --counter;
  
  ::std::ofstream  os("nextseq.out");
  os << counter << ::std::endl;
  
  return true; // Success.
}

// ___________________________________________________________________________

int
main
()
{ int  status;
  try
  { bool  const ok = Demo::process();
    status = ( ok ? 0 : 1 );
  }
  catch ( ... )
  { status = 2;
  }
  return status;
}