魔方问题的弟弟-----魔板问题,求解!

hproof 2001-02-08 09:51:00
魔板问题就是:一般的魔板比如3*3大小,开始是有完整的图象的(也可以是数据),在打乱后让你重新排回去。
看了很多书好象都是用递归算法,但如果魔板的大小是100*100甚至是,,,?有什么合适的算法非递归???

证明题:对开始为完整的魔板进行任意两个调换位置操作,如果调换的次数为奇数次,则魔板问题无解,请证明。

没看过很多算法书,自己提问。
ps:http://www.china139.com/club/disp.asp?owner=6005&ID=693&club=debug



...全文
271 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Sofoot 2001-07-19
  • 打赏
  • 举报
回复
如果不要求使用最少的步骤,我知道一个非递归的算法,是陈景润先生的一本书上介绍的,非常简单。至于证明,也很简单,前提是你要有一点线性代数的知识。
具体细节和我联系:sofoot@163.com
hproof 2001-02-11
  • 打赏
  • 举报
回复
好象又错了,证明1应该为:
abc abd
def---->ecf
不过具体的嘛,是d位置能走道c位置,而保持ab位置不变,这才是最重要的,
hproof 2001-02-11
  • 打赏
  • 举报
回复
其实我给出的地址是我以前想到过的方法,它不是递归或者广度、深度搜寻,它利用一种近似“智能”的方式。那篇文章写的不够细致,其主要思想为:

11111111111111111111
1111111111111111111
1111x。。。。。。。
。。。。。ca。。。
。。。b。。。。。。
。。。。。。。。。。。
1===》已经排好顺序,它的元素不可访问,除非特权
x===》应该考虑的下一个元素位置
.===》未知元素
c===》堵塞元素,它“挡”住了a前往x的路线
a===》下一个元素,它应该即将被插入到x的位置
b===》空格元素
解决思路:
0,顺序从上往下,从左往右;
1,考虑下一个元素a到它应该去的位置x的路线,计算它将需要先到达的c位置;
2,让空格b前往位置c,//这是很简单的问题,除非(特权),,,下面另有所述;
3,元素a可以去到c位置,因为现在c位置已经被空格b占有;
4,重复到1步骤。
上面的方法只要问题有解,则问题可解,除非。。。-》
1,当堵塞元素c在最右边,且它的上面和左边都为1元素,则空格元素怎样到达?
2,但计算到最底下1行时,空格元素怎样走动呢?因为这时上面的都是1元素,而1元素非“特权”情况下是不可访问的,以为着不能移动它们。
这两种情况都需要“特权”处理!
对于1情况,可以证明
abc abd
def-----》可以限制在该6个元素种变换到---》cef
即:元素d可以“前往”c元素,而把移动操作限制在该6个元素位置,这样,当“例外1“发生时,可以解决空格元素这种情况下前往堵塞元素位置的问题;
对于2情况,必须在处理到倒数第2行时就考虑,只要改变顺序,不再从上到下,从左到右,而是从左到右,从上到下,即先排好全部左边的顺序,然后再考虑右边下一列;

由于这种解法没有遍历每一种可能性,只要存在解,则它对数组大小及不敏感!!!

babysloth 2001-02-11
  • 打赏
  • 举报
回复
这个问题比较麻烦,一般都做不大,不妨用启发式搜索。
在《电脑爱好者》上面倒有过一个,不过也不大。
tjq 2001-02-10
  • 打赏
  • 举报
回复
显然是广度优先,查找最少步数,深度也可以,不一定最少,

证明题查看组合数学群论里面的置换里面的一些分解的原理即可,思路是将其任一分解成两两的积,若分解出来个数是偶的,则不可能有一种方案将其分解成奇的,反之亦然!
hproof 2001-02-10
  • 打赏
  • 举报
回复
能讲讲原理吗?
你的方法是不是能(要)求遍每一中可能性???我的pascal才考了70多分,看不太懂(也懒得看)。如果是,则方法错!
,,,你举例的是3*3大小?如果是100*100或者是10000*10000或者是,,,,,
friendkey 2001-02-10
  • 打赏
  • 举报
回复
其实就是“八数码难题”,可以用广度优先搜索。用队列存储结点。其实有了递归的算法,再改成非递归的也不会太难。
这是八数码难题的源程序,稍加修改就可以是魔版问题了。程序结果用数字表示,
如:
123804765
表示:
123
804
765
初始状态任意,目标为123804765

type {定义结点类型,用来表示状态}
box=string[9];
node=record
ch:box;{数字排列状态}
pnt:integer;{父结点}
pos:integer;{空格所在位置}
end;

const
start:box='123845076';{起始状态}
target:box='123804765';{目标状态}
step:array[1..4]of integer=(-3,3,-1,1);

var
data:array[1..500]of node;{队列}
now:node;
head,tail:integer;
next:node;

function check(r:integer):boolean;
begin
check:=((now.pos+step[r])in[1..9])and(not((now.pos mod 3=0)and(step[r]=1)or(now.pos mod 3=1)and(step[r]=-1)));
end;

procedure Move(r:integer);

begin
next:=now;
next.pos:=now.pos+step[r];
next.ch[now.pos]:=now.ch[next.pos];
next.ch[next.pos]:='0'
end;

function dupe:boolean;
var i:integer;
begin
dupe:=false;
for i:=head to tail-1 do
if data[i].ch=data[tail].ch then
begin
dupe:=true;
exit;
end;
end;

procedure pr;
var i:integer;
begin
writeln('success');
i:=tail;
writeln(data[i].ch);
repeat
i:=data[i].pnt;
writeln(data[i].ch);
until data[i].pnt=0;
halt
end;

var i:integer;
begin
head:=1;tail:=0;
now.ch:=start;
now.pos:=pos('0',start);
{data[head]:=now;}
repeat
for i:=1 to 4 do
begin
if check(i) then
begin
move(i);
inc(tail);
next.pnt:=head-1;
data[tail]:=next;
if dupe then
dec(tail)
else
if data[tail].ch=target then pr;
end;
end;
now:=data[head];
inc(head);
until tail<head;
writeln('No solution');
end.

至于证明题嘛,我再想想...

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧