você não especificou nenhum destinatário

Você tem certeza de que deseja enviar uma mensagem sem assunto?

Archive for the ‘C++’ Category

102 – Ecological Bin Packing

leave a comment »

102 – Ecological Bin Packing (pdf)

http://github.com/cirocavani/uva.onlinejudge.org-cxx/tree/master/102

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

struct N;
typedef std::vector<std::mem_fun_t<int, N> > F;

struct N
{

  int b, g, c;

  N(int _b = 0, int _g = 0, int _c = 0) : b(_b), g(_g), c(_c) { }

  friend std::istream& operator>>(std::istream& in, N& n)
  {
    return in >> n.b >> n.g >> n.c;
  }

  int value_b() { return b; }

  int value_g() { return g; }

  int value_c() { return c; }

};

struct W
{

  N n1, n2, n3;

  int m;

  std::string t;

  W() : m(0) { }

  friend std::istream& operator>>(std::istream& in, W& w)
  {
    return in >> w.n1 >> w.n2 >> w.n3 >> std::ws;
  }

  friend std::ostream& operator<<(std::ostream& out, const W& w)
  {
    return out << w.t << " " << w.m << std::endl;
  }

  std::string str(std::vector<std::string>& s, std::vector<std::size_t>& i)
  {
    std::string out;
    for (std::vector<std::size_t>::iterator p = i.begin(); p != i.end(); ++p)
      out += s[*p];
    return out;
  }

  W& min()
  {
    std::vector<N*> v;
    v.push_back(&n1);
    v.push_back(&n2);
    v.push_back(&n3);

    F f;
    f.push_back(std::mem_fun(&N::value_b));
    f.push_back(std::mem_fun(&N::value_g));
    f.push_back(std::mem_fun(&N::value_c));

    std::vector<std::string> s(f.size());
    s[0] = "B";
    s[1] = "G";
    s[2] = "C";

    std::vector<std::size_t> fi(f.size());
    for (std::size_t i = 0; i < fi.size(); ++i)
      fi[i] = i;

    m = 0;
    t = "";

    do
      {
	int n = 0;
	for (std::size_t i = 0; i < fi.size(); ++i)
	  for (std::size_t j = 0; j < v.size(); ++j)
	    n += i == j ? 0 : f[fi[i]](v[j]);

	if (m == 0 || m > n || (m == n && t > str(s, fi)))
	  {
	    m = n;
	    t = str(s, fi);
	  }
      }
    while (std::next_permutation(fi.begin(), fi.end()));

    return *this;
  }

};

void evaluate(W* w)
{
  std::cout << w->min();
}

int main()
{
  std::vector<W*> v;

  while (std::cin.good())
    {
      W* w = new W();
      std::cin >> *w;
      v.push_back(w);
    }

  std::for_each(v.begin(), v.end(), evaluate);

  return 0;
}

Written by Ciro Cavani

2011-02-19 at 1:45 am

Publicado em C++, Puzzle

101 – The Blocks Problem

leave a comment »

101 – The Blocks Problem (pdf)

http://github.com/cirocavani/uva.onlinejudge.org-cxx/tree/master/101

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <exception>

struct N;
typedef std::vector<N> U;
typedef std::vector<U> V;

struct N
{

  int i, x, y;

  N(int _i = -1) : i(_i), x(_i), y(0) { }

  friend std::ostream& operator<<(std::ostream& out, const N& n)
  {
    return out << n.i;
  }

};

struct W
{

  U u;

  V v;

  W(int n) : u(n), v(n)
  {
    for (int i = 0; i < n; ++i)
      {
	N o(i);
	u[i] = o;
	v[i].push_back(o);
      }
  }

  friend std::ostream& operator<<(std::ostream& out, const W& w)
  {
    for (std::size_t i = 0; i < w.v.size(); ++i)
      {
	out << i << ":";
	const U& k = w.v[i];
	for (std::size_t j = 0; j < k.size(); ++j)
	  out << " " << k[j];
	out << std::endl;
      }
    return out;
  }

  void moveonto(int i, int j)
  {
    try
      {
	assertNotEqual(i, j);

	const N& ni = u[i];
	const N& nj = u[j];
	assertNotEqual(ni.x, nj.x);

	const N& nix = u[ni.x];
	const N& njx = u[nj.x];
	assertNotOver(nix, ni);
	assertNotOver(njx, ni);
	assertNotOver(nix, nj);
	assertNotOver(njx, nj);

	moveback(ni.x, ni.y);
	moveback(nj.x, nj.y);
	move(ni.i, nj.x);
      }
    catch (std::exception& e)
      {
	// no-op
      }
  }

  void moveover(int i, int j)
  {
    try
      {
	assertNotEqual(i, j);

	const N& ni = u[i];
	const N& nj = u[j];
	assertNotEqual(ni.x, nj.x);

	const N& nix = u[ni.x];
	assertNotOver(nix, ni);

	moveback(ni.x, ni.y);
	move(ni.i, nj.x);
      }
    catch (std::exception& e)
      {
	// no-op
      }
  }

  void pileonto(int i, int j)
  {
    try
      {
	assertNotEqual(i, j);

	const N& ni = u[i];
	const N& nj = u[j];
	assertNotEqual(ni.x, nj.x);

	const N& njx = u[nj.x];
	assertNotOver(njx, nj);

	moveback(nj.x, nj.y);
	movepile(ni.i, nj.x);
      }
    catch (std::exception& e)
      {
	// no-op
      }
  }

  void pileover(int i, int j)
  {
    try
      {
	assertNotEqual(i, j);

	const N& ni = u[i];
	const N& nj = u[j];
	assertNotEqual(ni.x, nj.x);

	movepile(ni.i, nj.x);
      }
    catch (std::exception& e)
      {
	// no-op
      }
  }

private:

  void assertNotEqual(int i, int j)
  {
    if (i == j) throw std::exception();
  }

  void assertNotOver(const N& nx, const N& n)
  {
    if (nx.x == n.x && nx.y > n.y) throw std::exception();
  }

  void moveback(int x, std::size_t y)
  {
    U& k = v[x];
    while (k.size() > y + 1)
      {
	int i = k.back().i;
	k.pop_back();
	put(u[i], i);
      }
  }

  void move(int i, int x)
  {
    N& n = u[i];
    U& k = v[n.x];
    k.erase(k.begin() + n.y);
    put(n, x);
  }

  void movepile(int i, int x)
  {
    N& n = u[i];
    U& k = v[n.x];
    for (U::iterator p = k.begin() + n.y; p != k.end(); p = k.erase(p))
      put(u[p->i], x);
  }

  void put(N& n, int x)
  {
    U& m = v[x];
    n.x = x;
    n.y = m.size();
    m.push_back(n);
  }

};

struct M
{

  std::string m1, m2;

  int i, j;

};

int main()
{
  int n;

  std::cin >> n;

  W w(n);

  std::vector<M> v;

  while (true)
    {
      std::string m0;
      std::cin >> m0;

      if (m0 == "quit")
	break;

      M m;
      m.m1 = m0;
      std::cin >> m.i >> m.m2 >> m.j >> std::ws;

      v.push_back(m);
    }

  for (std::vector<M>::iterator p = v.begin(); p != v.end(); ++p)
    {
      if (p->m1 == "move" && p->m2 == "onto")
	w.moveonto(p->i, p->j);
      else if (p->m1 == "move" && p->m2 == "over")
	w.moveover(p->i, p->j);
      else if (p->m1 == "pile" && p->m2 == "onto")
	w.pileonto(p->i, p->j);
      else if (p->m1 == "pile" && p->m2 == "over")
	w.pileover(p->i, p->j);
    }

  std::cout << w;

  return 0;
}

Written by Ciro Cavani

2011-02-19 at 1:43 am

Publicado em C++, Puzzle

100 – The 3n + 1 problem

leave a comment »

100 – The 3n + 1 problem (pdf)

http://github.com/cirocavani/uva.onlinejudge.org-cxx/tree/master/100

#include <iostream>
#include <vector>
#include <algorithm>

struct N
{

  int s, e, m;

  N() : s(1), e(1), m (1) { }

  friend std::istream& operator>>(std::istream& in, N& n)
  {
    return in >> n.s >> n.e >> std::ws;
  }

  friend std::ostream& operator<<(std::ostream& out, const N& n)
  {
    return out << n.s << " " << n.e << " " << n.m << std::endl;
  }

  int count(int n)
  {
    if (n == 1)
      return 1;

    int count = 2; // 1 and n
    while ((n = n % 2 == 0 ? n / 2 : 3 * n + 1) != 1)
      ++count;

    return count;
  }

  N& max()
  {
    m = 0;
    const int _s = std::min(s, e);
    const int _e = std::max(s, e);
    for (int i = _s; i <= _e; ++i)
      m = std::max(m, count(i));
    return *this;
  }

};

void evaluate(N& n)
{
  std::cout << n.max();
}

int main()
{
  std::vector<N> v;

  while (std::cin.good())
    {
      N n;
      std::cin >> n;
      v.push_back(n);
    }

  std::for_each(v.begin(), v.end(), evaluate);

  return 0;
}

Written by Ciro Cavani

2011-02-19 at 1:40 am

Publicado em C++, Puzzle