Codevs p1004四子连棋
首先说明,由于本人实力低下,所以代码极其冗长。。。。
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
●|○|●|空|
○|●|○| ●|
●|○|●| ○|
○|●|○|空|
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
分析
直接进行bfs,当第一次找到符合题意的解时便退出程序。肯定是最少步数。
代码如下(实力有限)
program p1004;
const dx:array[1..4] of integer=(1,0,-1,0);
dy:array[1..4] of integer=(0,1,0,-1);
type ar=array[1..4,1..4] of longint;
var can:array[1..100000] of ar;
queue:array[1..100000] of record
x1,y1,x2,y2,step,pre:longint;
now:ar;
end;
ch:char;
form:ar;
flag:boolean;
i,j,k,head,rear,sum:longint;
function complete(x,y:longint):boolean;
var i,j:longint;
flag:boolean;
begin
flag:=true;
for i:=1 to 4 do
begin
if form[x,i]<>form[x,y]
then
begin
flag:=false;
break;
end;
end;
if flag then exit(true);
flag:=true;
for i:=1 to 4 do
begin
if form[i,y]<>form[x,y]
then
begin
flag:=false;
break;
end;
end;
if flag then exit(true);
flag:=true;
if x+y=5
then
begin
for i:=1 to 4 do
begin
if form[i,5-i]<>form[x,y]
then
begin
flag:=false;
break;
end;
end;
if flag then exit(true);
end;
flag:=true;
if x=y
then
begin
for i:=1 to 4 do
begin
if form[i,i]<>form[x,y]
then
begin
flag:=false;
break;
end;
end;
if flag then exit(true);
end;
exit(false);
end;
function same:boolean;
var i,j,k:longint;
flag:boolean;
begin
for k:=1 to sum do
begin
flag:=false;
for i:=1 to 4 do
begin
for j:=1 to 4 do
if form[i,j]<>can[k,i,j]
then
begin
flag:=true;
break;
end;
if flag then break;
end;
if not flag then exit(true);
end;
exit(false);
end;
procedure bfs;
var x,y,k:longint;
begin
while head<=rear do
begin
for k:=1 to 4 do
begin
x:=queue[head].x1+dx[k];
y:=queue[head].y1+dy[k];
form:=queue[head].now;
if (x>0) and (x<=4) and (y>0) and (y<=4) and (form[x,y]<>queue[head].pre)
then
begin
form[queue[head].x1,queue[head].y1]:=form[x,y];
form[x,y]:=0;
if complete(queue[head].x1,queue[head].y1)
then
begin
writeln(queue[head].step+1);
exit;
end;
if not same
then
begin
inc(rear);
queue[rear].x1:=x;
queue[rear].y1:=y;
queue[rear].x2:=queue[head].x2;
queue[rear].y2:=queue[head].y2;
queue[rear].pre:=form[queue[head].x1,queue[head].y1];
queue[rear].now:=form;
queue[rear].step:=queue[head].step+1;
inc(sum);
can[sum]:=form;
end;
end;
end;
for k:=1 to 4 do
begin
x:=queue[head].x2+dx[k];
y:=queue[head].y2+dy[k];
form:=queue[head].now;
if (x>0) and (x<=4) and (y>0) and (y<=4) and (form[x,y]<>queue[head].pre)
then
begin
form[queue[head].x2,queue[head].y2]:=form[x,y];
form[x,y]:=0;
if complete(queue[head].x2,queue[head].y2)
then
begin
writeln(queue[head].step+1);
exit;
end;
if not same
then
begin
inc(rear);
queue[rear].x1:=queue[head].x1;
queue[rear].y1:=queue[head].y1;
queue[rear].x2:=x;
queue[rear].y2:=y;
queue[rear].pre:=form[queue[head].x2,queue[head].y2];
queue[rear].now:=form;
queue[rear].step:=queue[head].step+1;
inc(sum);
can[sum]:=form;
end;
end;
end;
inc(head);
end;
end;
begin
head:=1;
rear:=1;
flag:=true;
for i:=1 to 4 do
begin
for j:=1 to 4 do
begin
read(ch);
case ch of
'B':begin
queue[1].now[i,j]:=1;
can[1,i,j]:=1;
end;
'W':begin
queue[1].now[i,j]:=2;
can[1,i,j]:=2;
end;
'O':begin
queue[1].now[i,j]:=0;
can[1,i,j]:=0;
if flag
then
begin
queue[1].x1:=i;
queue[1].y1:=j;
flag:=false;
end
else
begin
queue[1].x2:=i;
queue[1].y2:=j;
end;
queue[1].step:=0;
end;
end;
end;
readln;
end;
queue[1].pre:=-1;
sum:=1;
bfs;
end.
测试结果
测试通过 Accepted
总耗时: 4 ms
0 / 0 数据通过测试.
运行结果
测试点#chess.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms
测试点#chess1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess10.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess2.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms
测试点#chess3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess4.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess5.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess6.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess7.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#chess8.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms
测试点#chess9.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms
想
missing U