Nguồn đề bài: CHESSCBG
1. Đề bài CHESSCBG spoj
Một bàn cờ thế là một bảng gồm 4 dòng, 4 cột. Mỗi thế cờ là một cách sắp xếp 8 quân cờ, hai quân khác nhau ở hai ô khác nhau. Bài toán đặt ra là cho hai thế cờ 1 và 2, hãy tìm một số ít nhất bước di chuyển quân để chuyển từ thế 1 sang thế 2; một bước di chuyển quân là một lần chuyển quân cờ sang ô trống kề cạnh với ô quân cờ đang đứng.
Dữ liệu vào
Từ file văn bản gồm 8 dòng, mỗi dòng là một xâu nhị phân độ dài 4 mà số 1/0 tương ứng với vị trí có hoặc không có quân cờ. Bốn dòng đầu là thế cờ 1, bốn dòng sau là thế cờ 2.
Dữ liệu ra
Gồm 1 dòng duy nhất là số bước chuyển quân ít nhất
Ví dụ
Dữ liệu vào:
1111
0000
1110
0010
1010
0101
1010
0101
Dữ liệu ra :
4
2. Code tham khảo CHESSCBG spoj
Pascal
const fi='';
H:array[1..4] of longint=(-1,4,-4,1);
maxbit=66000;
type
data=word;
var
f:text;
x,y:data;
Q:array[0..maxbit] of data;
C:array[0..maxbit] of data;
sd:array[1..16] of data;
D:array[1..16,1..4] of data;
dau,cuoi:data;
function getbit(k,x:data):byte;
begin
getbit:=(x shr (k-1)) and 1;
end;
procedure Setbit(c,k:byte; var x:data);
begin
if c=1 then
x:=x or (1 shl (k-1))
else
x:=x and (not (1 shl (k-1)));
end;
procedure docfile;
var i,j:data;
c:char;
begin
assign(f,fi); reset(f);
x:=0;
y:=0;
for i:=1 to 16 do
begin
read(f,c);
if c='1' then
setbit(1,i,x);
if i mod 4 = 0 then
readln(f);
end;
for i:=1 to 16 do
begin
read(f,c);
if c='1' then
setbit(1,i,y);
if i mod 4 = 0 then
readln(f);
end;
close(f);
end;
procedure init;
var i,j,dau,cuoi:data;
tinh:integer;
begin
fillchar(sd,sizeof(sd),0);
fillchar(d,sizeof(d),0);
for i:=1 to 16 do
begin
dau:=1;
cuoi:=4;
if i and 3 = 1 then
dau:=2
else
if i and 3 = 0 then
cuoi:=3;
for j:=dau to cuoi do
begin
tinh:=i+h[j];
if tinh in [1..16] then
begin
inc(sd[i]);
d[i,sd[i]]:=tinh;
end;
end;
end;
end;
procedure themvao(x,y:data);
begin
inc(cuoi);
Q[cuoi]:=x;
c[x]:=y;
end;
function layra:data;
begin
layra:=q[dau];
inc(dau);
end;
Function gt(x,i: data):data;
Begin
if GetBit(i,x)=1 then
exit(254);
gt:=x;
SetBit(1,i,gt);
End;
procedure bfs;
var i,j,bit,tt:data;
tinh:data;
begin
init;
dau:=1;
cuoi:=0;
fillchar(c,sizeof(c),0);
C[254]:=100;
themvao(x,1);
while (dau<=cuoi) do
begin
bit:=layra;
tt:=c[bit]+1;
for i:=1 to 16 do
if getbit(i,bit)=1 then
begin
setbit(0,i,bit);
for j:=1 to sd[i] do
begin
tinh:=gt(bit,d[i,j]);
if c[tinh]=0 then
begin
themvao(tinh,tt);
if c[y]<>0 then
exit;
end;
end;
setbit(1,i,bit);
end;
end;
end;
begin
docfile;
bfs;
writeln(c[y]-1);
end.
C++
#include <bits/stdc++.h>
using namespace std;
int Start, End;
int first, last;
vector<int> Visit,d,mu2;
queue<int> que;
void Init()
{
ios_base::sync_with_stdio(false);
mu2.resize(50);
mu2[16]=1;
for (int i=15;i>0;i--)
{
mu2[i]=mu2[i+1]*2;
}
char tg;
for (int i=1;i<=16;i++)
{
cin>>tg;
if(tg=='1') Start+=mu2[i];
}
for (int i=1;i<=16;i++)
{
cin>>tg;
if(tg=='1') End+=mu2[i];
}
Visit.resize(mu2[1]*2+2);
d.resize(mu2[1]*2+2);
}
void TryLeft(int u, int i)
{
int v=u-mu2[i]+mu2[i-1];
if(!Visit[v])
{
que.push(v);
d[v]=d[u]+1;
Visit[v]=true;
}
}
void TryRight(int u, int i)
{
int v=u-mu2[i]+mu2[i+1];
if(!Visit[v])
{
que.push(v);
d[v]=d[u]+1;
Visit[v]=true;
}
}
void TryUp(int u, int i)
{
int v=u-mu2[i]+mu2[i-4];
if(!Visit[v])
{
que.push(v);
d[v]=d[u]+1;
Visit[v]=true;
}
}
void TryDown(int u, int i)
{
int v=u-mu2[i]+mu2[i+4];
if(!Visit[v])
{
que.push(v);
d[v]=d[u]+1;
Visit[v]=true;
}
}
void Solve()
{
que.push(Start);
Visit[Start]=true;
while (!que.empty())
{
int u=que.front();
que.pop();
if(u==End)
{
cout<<d[End];
return;
}
for (int i=1;i<=16;i++)
{
if((u&mu2[i])!=0)
{
if(i%4!=1 && (u&mu2[i-1])==0)
TryLeft(u,i);
if(i%4!=0 && (u&mu2[i+1])==0)
TryRight(u,i);
if(i>4 && (u&mu2[i-4])==0)
TryUp(u,i);
if(i<13 && (u&mu2[i+4])==0)
TryDown(u,i);
}
}
}
}
int main()
{
Init();
Solve();
}