Created
April 16, 2013 17:16
-
-
Save odarbelaeze/5397706 to your computer and use it in GitHub Desktop.
The blocks problem http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <exception> | |
#include <iostream> | |
#include <sstream> | |
#include <string> | |
// 1234-------- | |
template<typename T> | |
class Stack | |
{ | |
public: | |
Stack() | |
{ | |
allocated_ = 1; | |
N_ = 0; | |
data_ = new T[allocated_]; | |
} | |
~Stack() { | |
delete[] data_; | |
} | |
void push(T item) | |
{ | |
if (N_ == allocated_) | |
{ | |
T* copy = data_; | |
allocated_ *= 2; | |
data_ = new T[allocated_]; | |
for (int i = 0; i < N_; ++i) | |
data_[i] = copy[i]; | |
} | |
data_[N_++] = item; | |
} | |
T pop() | |
{ | |
if (N_ == 0) throw std::exception(); | |
if (N_ == allocated_ / 4) | |
{ | |
T* copy = data_; | |
allocated_ /= 2; | |
data_ = new T[allocated_]; | |
for (int i = 0; i < N_; ++i) | |
data_[i] = copy[i]; | |
} | |
return data_[--N_]; | |
} | |
T top() | |
{ | |
return data_[N_ - 1]; | |
} | |
bool contains(const T& item) | |
{ | |
bool flag = false; | |
for (int i = 0; i < N_; ++i) | |
{ | |
if (data_[i] == item) | |
{ | |
flag = true; | |
} | |
} | |
return flag; | |
} | |
bool isEmpty() { | |
return N_ == 0; | |
} | |
size_t size() | |
{ | |
return N_; | |
} | |
T operator[] (int i) | |
{ | |
return data_[i]; | |
} | |
private: | |
T* data_; | |
size_t allocated_; | |
size_t N_; | |
}; | |
class BlocksWorld | |
{ | |
public: | |
BlocksWorld(int N) { | |
N_ = N; | |
data_ = new Stack<int>[N_]; | |
for (int i = 0; i < N_; ++i) | |
{ | |
data_[i].push(i); | |
} | |
} | |
~BlocksWorld() { | |
delete[] data_; | |
} | |
void print() { | |
for (int i = 0; i < N_; ++i) | |
{ | |
std::cout << i << ": "; | |
for (int j = 0; j < data_[i].size(); ++j) | |
{ | |
std::cout << data_[i][j] << " "; | |
} | |
std::cout << std::endl; | |
} | |
} | |
void moveOnto(int a, int b) { | |
int id_a = find_(a); | |
int id_b = find_(b); | |
Stack<int> aux_a; | |
Stack<int> aux_b; | |
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop()); | |
while (data_[id_b].top() != b) aux_b.push(data_[id_b].pop()); | |
data_[id_a].pop(); | |
data_[id_b].pop(); | |
while (!aux_a.isEmpty()) data_[aux_a.top()].push(aux_a.pop()); | |
while (!aux_b.isEmpty()) data_[aux_b.top()].push(aux_b.pop()); | |
data_[id_b].push(b); | |
data_[id_b].push(a); | |
} | |
void moveOver(int a, int b) { | |
int id_a = find_(a); | |
int id_b = find_(b); | |
Stack<int> aux_a; | |
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop()); | |
data_[id_a].pop(); | |
while (!aux_a.isEmpty()) data_[aux_a.top()].push(aux_a.pop()); | |
data_[id_b].push(a); | |
} | |
void pileOnto(int a, int b) { | |
int id_a = find_(a); | |
int id_b = find_(b); | |
Stack<int> aux_a; | |
Stack<int> aux_b; | |
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop()); | |
while (data_[id_b].top() != b) aux_b.push(data_[id_b].pop()); | |
aux_a.push(data_[id_a].pop()); | |
while (!aux_a.isEmpty()) data_[id_b].push(aux_a.pop()); | |
while (!aux_b.isEmpty()) data_[aux_b.top()].push(aux_b.pop()); | |
} | |
void pileOver(int a, int b) { | |
int id_a = find_(a); | |
int id_b = find_(b); | |
Stack<int> aux_a; | |
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop()); | |
aux_a.push(data_[id_a].pop()); | |
while (!aux_a.isEmpty()) data_[id_b].push(aux_a.pop()); | |
} | |
private: | |
size_t N_; | |
Stack<int>* data_; | |
int find_(int item) | |
{ | |
int pos = 0; | |
while(!data_[pos].contains(item)) pos++; | |
return pos; | |
} | |
}; | |
int main(int argc, char const *argv[]) | |
{ | |
char buffer[50]; | |
char verb[10]; | |
char adverb[10]; | |
int n, a, b; | |
std::gets(buffer); | |
std::sscanf(buffer, "%d\n", &n); | |
BlocksWorld bw(n); | |
// Command parser | |
while (std::gets(buffer)) | |
{ | |
if (std::string(buffer) == "quit") break; | |
std::sscanf(buffer, "%s %d %s %d\n", verb, &a, adverb, &b); | |
if (std::string(verb) == "move") | |
{ | |
if (std::string(adverb) == "onto") | |
{ | |
bw.moveOnto(a, b); | |
} | |
else if (std::string(adverb) == "over") | |
{ | |
bw.moveOver(a, b); | |
} | |
} | |
else if (std::string(verb) == "pile") | |
{ | |
if (std::string(adverb) == "onto") | |
{ | |
bw.pileOnto(a, b); | |
} | |
else if (std::string(adverb) == "over") | |
{ | |
bw.pileOver(a, b); | |
} | |
} | |
} | |
bw.print(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment