【POJ1208】The Blocks Problem

本文介绍了一种解决木块问题的算法实现,通过定义函数f(i)将木块i上的其他木块放回初始位置,m(i,j)将木块i及以上的木块移动到包含j的上方等操作来实现木块的移动与堆叠。

来源: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 ;
}

 

 

 

转载于:https://www.cnblogs.com/tuty/archive/2010/09/27/1836596.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值