Cod sursa(job #905452)

Utilizator aleph0Ionut-Gabriel Radu aleph0 Data 5 martie 2013 20:39:40
Problema Subsir Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iostream>

class LCSTable
{
  private:
    size_t m_;
    size_t n_;
    size_t mod_;
    size_t* data_;
    size_t* sol_;

    size_t getSolAt(size_t i, size_t j) const
    {
      return sol_[i + j * (m_ + 1)];
    }

    void setSolAt(size_t i, size_t j, size_t val)
    {
      sol_[i + j * (m_ + 1)] = val;
    }

  public:
    LCSTable(size_t m, size_t n, size_t mod)
    : m_(m), n_(n), mod_(mod)
    {
      data_ = new size_t [(m + 1) * (n + 1)];
      sol_ = new size_t [(m + 1) * (n + 1)];
    }

    LCSTable(const LCSTable& other)
    : m_(other.m_),
      n_(other.n_),
      mod_(other.mod_),
      data_(new size_t [(other.m_ + 1) * (other.n_ + 1)]),
      sol_(new size_t [(other.m_ + 1) * (other.n_ + 1)])
    {
      std::copy(other.data_,
                other.data_ + (other.m_ + 1) * (other.n_ + 1),
                data_);
    }

    ~LCSTable()
    {
      delete [] data_;
      delete [] sol_;
    }

    LCSTable& operator=(const LCSTable& rhs) {
      if (this != &rhs) {
        m_ = rhs.m_;
        n_ = rhs.n_;
        mod_ = rhs.mod_;
        size_t size = (rhs.m_ + 1) * (rhs.n_ + 1);
        delete [] data_;
        data_ = new size_t [size];
        std::copy(rhs.data_,
                  rhs.data_ + size,
                  data_);
        delete [] sol_;
        sol_ = new size_t [size];
        std::copy(rhs.sol_,
                  rhs.sol_ + size,
                  sol_);
      }
      return *this;
    }

    size_t getAt(size_t i, size_t j) const
    {
      return data_[i + j * (m_ + 1)];
    }

    void setAt(size_t i, size_t j, size_t value)
    {
      data_[i + j * (m_ + 1)] = value;
    }

    template <class T>
    size_t build(const T& X, const T& Y)
    {
      for (size_t i = 0; i <= m_; ++i) {
        setAt(i, 0, 0);
        setSolAt(i, 0, 1);
      }

      for (size_t j = 0; j <= n_; ++j) {
        setAt(0, j, 0);
        setSolAt(0, j, 1);
      }

      for (size_t i = 0; i < m_; ++i) {
        for (size_t j = 0; j < n_; ++j) {
          if (X[i] == Y[j]) {
            setAt(i + 1, j + 1, getAt(i, j) + 1);
          } else {
            setAt(i + 1, j + 1, std::max(getAt(i + 1, j), getAt(i, j + 1)));
          }
        }
      }

      for (size_t i = 1; i <= m_; i++) {
        for (size_t j = 1; j <= n_; j++) {
          int dij = 0;
          if (X[i - 1] == Y[j - 1]) {
            dij = getSolAt(i - 1, j - 1);
          } else if (getAt(i, j) == getAt(i - 1, j)) {
            dij = (dij + getSolAt(i - 1, j)) % mod_;
          }

          if (getAt(i, j) == getAt(i, j - 1)) {
            dij = (dij + getSolAt(i, j - 1)) % mod_;
          }

          if (getAt(i, j) == getAt(i - 1, j - 1)) {
            dij = (dij - getSolAt(i - 1, j - 1) + mod_) % mod_;
          }

          setSolAt(i, j, dij);
        }
      }

      return getSolAt(m_, n_);
    }
};

int main(int argc, char** argv)
{

  std::ifstream in("subsir.in");
  std::ofstream out("subsir.out");
  std::string s1;
  std::string s2;
  in >> s1;
  in >> s2;
  int m = s1.size();
  int n = s2.size();
  int max = std::max(m, n);
  int min = std::min(m, n);

  LCSTable lcs(max, min, 666013);

  if (m == max) {
    out << lcs.build<std::string>(s1, s2);
  } else {
    out << lcs.build<std::string>(s2, s1);
  }

  in.close();
  out.close();
  return 0;
}