八数码问题 广度优先搜索+枚举判重

const MaxN=500000;

type
  atp=record
    s:string;
    time:longint;
  end;

var
  que:array[0..MaxN] of atp;
  head,tail,x:longint;
  now:string;//存储进行操作后的字符串

procedure print;//判断是否找到了目标状态
begin
  if que[tail].s='123804765' then
     begin
       writeln(que[tail].time);
       halt;
     end;
end;

function judge:boolean;//用枚举查找是否在之前的状态中出现过
var i:longint;
begin
  for i:= 1 to tail do
     if que[i].s=now then exit(false);
  exit(true);
end;

begin
  head:=1; tail:=1;
  readln(que[head].s);
  que[head].time:=0;
  print;
  while head<=tail do
    begin
      x:=pos('0',que[head].s);//查找当前状态的空格位置,以进行操作

      if ( (x-1) div 3>0 ) then //空格可以向上移动
         begin
           now:=que[head].s;
           now[x]:=now[x-3];
           now[x-3]:='0';
           if judge then
              begin
                inc(tail);
                que[tail].s:=now;
                que[tail].time:=que[head].time+1;
                print;
              end;
         end;

      if ( (x-1) div 3<2 ) then //空格可以向下移动
         begin
           now:=que[head].s;
           now[x]:=now[x+3];
           now[x+3]:='0';
           if judge then
              begin
                inc(tail);
                que[tail].s:=now;
                que[tail].time:=que[head].time+1;
                print;
              end;
         end;

      if ( (x-1) mod 3>0 ) then //空格可以向左移动
         begin
           now:=que[head].s;
           now[x]:=now[x-1];
           now[x-1]:='0';
           if judge then
              begin
                inc(tail);
                que[tail].s:=now;
                que[tail].time:=que[head].time+1;
                print;
              end;
         end;

      if ( (x-1) mod 3<2 ) then //空格可以向右移动
         begin
           now:=que[head].s;
           now[x]:=now[x+1];
           now[x+1]:='0';
           if judge then
              begin
                inc(tail);
                que[tail].s:=now;
                que[tail].time:=que[head].time+1;
                print;
              end;
         end;
      Inc(head);
    end;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值