#include <iostream>
using namespace std;
class Node
{
public:
Node(int m_tp,int c_tp,int b_tp,int deep_tp,int cost_tp,Node* p);
void set_m(int m_tp){m=m_tp;return;}
void set_c(int c_tp){c=c_tp;return;}
void set_b(int b_tp){b=b_tp;return;}
void set_cost(int cost_tp){cost=cost_tp;return;}
void set_deep(int deep_tp){deep=deep_tp;return;}
void set_next(Node* p){next=p;return;}
int get_m(){return m;}
int get_c(){return c;}
int get_b(){return b;}
int get_cost(){return cost;}
int get_deep(){return deep;}
Node* get_next(){return next;}
Node* get_parent(){return parent;}
void set_parent(Node* p){parent=p;return;}
bool judge_result();
bool judge_rationality();
void print_node();
private:
int m;
int c;
int b;
int cost;
int deep;
Node* parent;
Node* next;
};
class Operate
{
public:
Node* R(Node* p,int m_tp,int c_tp);
Node* L(Node* p,int m_tp,int c_tp);
};
class Stack
{
public:
Node* head;
Node* end;
void create_a_stack();
Node* get_head();
void add_end(Node* p);
void join_stack(Node* p);
};
int f(int m_tp,int c_tp,int b_tp,int deep_tp)
{
int vaule;
vaule= m_tp+c_tp-2*b_tp+deep_tp;
return vaule;
}
//for class Node
Node::Node(int m_tp,int c_tp,int b_tp,int deep_tp,int cost_tp,Node* p):m(m_tp),c(c_tp),b(b_tp),deep(deep_tp),cost(cost_tp),parent(p)
{
next=NULL;
}
bool Node::judge_result()
{
if((!m)&&(!c)&&(!b))
return true;
else
return false;
}
void Node::print_node()
{
cout << m << " " << c << " " << b << endl;
return;
}
bool Node::judge_rationality()
{
if(m<0||m>3||c<0||c>3||(m<c&&m!=0))
return false;
else
return true;
}
//for class Operate
Node* Operate::R(Node* p,int m_tp,int c_tp)
{
int m;
int c;
int b=0;
int d;
int cost;
Node* q;
m=p->get_m()-m_tp;
c=p->get_c()-c_tp;
d=p->get_deep()+1;
cost=f(m,c,b,d);
q= new Node(m,c,b,d,cost,p);
return q;
}
Node* Operate::L(Node* p,int m_tp,int c_tp)
{
int m;
int c;
int b=1;
int d;
int cost;
Node* q;
m=p->get_m()+m_tp;
c=p->get_c()+c_tp;
d=p->get_deep()+1;
cost=f(m,c,b,d);
q= new Node(m,c,b,d,cost,p);
return q;
}
//for class Stack
void Stack::create_a_stack()
{
Node* p= new Node(0,0,0,0,0,NULL);
head=p;
end=p;
return;
}
Node* Stack::get_head()
{
Node* temp;
temp=head->get_next();
if(temp==NULL)
{
cout << "there is no node" << endl;
return NULL;
}
head->set_next(temp->get_next());
if(temp==end)
{
end=head;
}
temp->set_next(NULL);
return temp;
}
void Stack::add_end(Node* p)
{
end->set_next(p);
end=end->get_next();
return;
}
void Stack::join_stack(Node* p)
{
if(!(p->judge_rationality()))
return;
else
{
Node* temp;
Node* tmp;
temp=head;
tmp=head->get_next();
while(!(temp->get_next()==NULL))
{
if(tmp->get_cost()>=p->get_cost())
{
temp->set_next(p);
p->set_next(tmp);
break;
}
temp=temp->get_next();
tmp=tmp->get_next();
}
if(tmp==NULL)
{
temp->set_next(p);
end=end->get_next();
}
}
return;
}
void start()
{
Stack open;
Stack close;
Node* temp;
Node* newnode;
Operate operate;
Node* s0 = new Node(3,3,1,0,f(3,3,1,0),NULL);
open.create_a_stack();
close.create_a_stack();
open.join_stack(s0);
while(!(open.head->get_next()==NULL))
{
temp=open.get_head();
close.join_stack(temp);
if(temp->judge_result())
{
cout << "success" << endl;
while(!(temp->get_parent()==NULL))
{
temp->print_node();
temp=temp->get_parent();
}
return;
}
if(temp->get_b())
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i+j>2)
continue;
else if((i==0)&&(j==0))
continue;
else
{
newnode=operate.R(temp,i,j);
if((3-newnode->get_m())<(3-newnode->get_c())&&newnode->get_m()!=3)
continue;
else
{
open.join_stack(newnode);
}
}
}
}
}
else
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i+j>2)
continue;
else if((i==0)&&(j==0))
continue;
else
{
newnode=operate.L(temp,i,j);
if((3-newnode->get_m())<(3-newnode->get_c())&&newnode->get_m()!=3)
continue;
else
{
open.join_stack(newnode);
}
}
}
}
}
}
cout << "fail " << endl;
return;
}
int main()
{
start();
return 0;
}