【POJ1208】The Blocks Problem
推导:(略)
设计:
f(i): 把叠在木块i上的其他木块放回初始位置.
m(i,j): 把i及其以上的木块全叠到包含j的上方.
move a onto b => f(a),f(b),m(a,b)
move a over b => f(a),m(a,b)
pile a onto b => f(b),m(a,b)
pile a over b => m(a,b)
代码:
#include <iostream>
using namespace std;
#define N 24
//块
struct Node{
int No; //编号
struct Node *next;
};
struct Node *station[N];//原始的块位置
int place[N];//当前各块所在的位置
struct Node *Find(int i,bool setNULL)
{
struct Node *p,*q;
int j = place[i];
if(station[j]->No == i)
{
p=station[j];
if(setNULL)
station[j] = NULL;
return p;
}
else
{
q=station[j];
p=q->next;
while(p->No!=i)
{
q=p;
p=q->next;
}
if(setNULL)
q->next=NULL;
return p;
}
}
void F(int i)
{
struct Node *p;
p=Find(i,false);
if(p->next==NULL)
return;
int j;
while(p->next!=NULL)
{
j = p->next->No;
station[j] = p->next;
place[j] = j;
p->next=NULL;
p=station[j];
}
}
void M(int i,int j)
{
if( i==j || place[i]==place[j] )
return;
struct Node *p,*q;
p=Find(i,true);
q=Find(j,false);
while(q->next!=NULL)
q=q->next;
q->next = p;
while(p!=NULL)
{
place[p->No]=place[q->No];
p=p->next;
}
}
void MoveAOntoB(int i,int j)
{
F(i);
F(j);
M(i,j);
}
void MoveAOverB(int i,int j)
{
F(i);
M(i,j);
}
void PileAOntoB(int i,int j)
{
F(j);
M(i,j);
}
void PileAOverB(int i,int j)
{
M(i,j);
}
void Init()
{
for( int i=0;i<N;i++ )
{
place[i] = i;
station[i] = (struct Node *)malloc(sizeof(struct Node));
station[i]->No = i;
station[i]->next = NULL;
}
}
int main()
{
int n;
char ch1[5],ch2[5];
int a,b;
struct Node *p;
cin >> n;
Init();
while(cin >> ch1 && strcmp(ch1,"quit")!=0 )
{
cin >> a;
cin >> ch2;
cin >> b;
if( strcmp(ch1,"move")==0 )
{
if( strcmp(ch2,"onto")==0 )
MoveAOntoB(a,b);
else
MoveAOverB(a,b);
}
else
{
if( strcmp(ch2,"onto")==0 )
PileAOntoB(a,b);
else
PileAOverB(a,b);
}
}
for( int i=0;i<n;i++ )
{
cout<<i<<": ";
p = station[i];
while(p!=NULL)
{
cout<<p->No<<" ";
p=p->next;
}
cout << endl;
}
return 1;
}