求教中国象棋马的一种极小覆盖(考虑别马腿)

hubinjushi 2001-11-26 01:04:39
我觉得应该用回朔,但是当你摆了一个马以后,下一个搜索位置在哪
...全文
389 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hubinjushi 2001-11-28
  • 打赏
  • 举报
回复
原代码不必了,你能说说你的评估函数吗
flylzz 2001-11-28
  • 打赏
  • 举报
回复
要五指棋的C源代码的找我,湖大的
hubinjushi 2001-11-28
  • 打赏
  • 举报
回复
哈哈,我已搞定,我是从任意一种满覆盖开始(可选最简单的一种),利用回溯,删去可去的马(考虑别马脚),源代码如下:
//////////////////////////////////
// 中国象棋马的一种极小覆盖 //
// by huanghe //
// 2001-11-28 //
//////////////////////////////////
program horse2;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
col=9;
line=10;
type
node=record
x,y:integer;
end;
successorarray=array[1..8]of node;
var
board:array[1..col,1..line]of integer;
delhorseok:array[1..col,1..line]of boolean;
i,j:integer;
////////////////////////////////
// procedure of select //
////////////////////////////////


procedure select(i,j:integer;var count:integer;var successor:successorarray);
begin
count:=0;
if (i-1>=1)and(j+2<=line)and(board[i-1][j+1]=0)and(board[i-1][j+2]=1)
then begin
inc(count);
successor[count].x:=i-1;
successor[count].y:=j+2;
end;
if (i+1<=col)and(j+2<=line)and(board[i+1][j+1]=0)and(board[i+1][j+2]=1)
then begin
inc(count);
successor[count].x:=i+1;
successor[count].y:=j+2;
end;
if (i+2<=col)and(j+1<=line)and(board[i+1][j+1]=0)and(board[i+2][j+1]=1)
then begin
inc(count);
successor[count].x:=i+2;
successor[count].y:=j+1;
end;
if (i+2<=col)and(j-1>=1)and(board[i+1][j-1]=0)and(board[i+2][j-1]=1)
then begin
inc(count);
successor[count].x:=i+2;
successor[count].y:=j-1;
end;
if (i+1<=col)and(j-2>=1)and(board[i+1][j-1]=0)and(board[i+1][j-2]=1)
then begin
inc(count);
successor[count].x:=i+1;
successor[count].y:=j-2;
end;
if (i-1>=1)and(j-2>=1)and(board[i-1][j-1]=0)and(board[i-1][j-2]=1)
then begin
inc(count);
successor[count].x:=i-1;
successor[count].y:=j-2;
end;
if (i-2>=1)and(j-1>=1)and(board[i-1][j-1]=0)and(board[i-2][j-1]=1)
then begin
inc(count);
successor[count].x:=i-2;
successor[count].y:=j-1;
end;
if (i-2>=1)and(j+1<=line)and(board[i-1][j+1]=0)and(board[i-2][j+1]=1)
then begin
inc(count);
successor[count].x:=i-2;
successor[count].y:=j+1;
end;
end;

//////////////////////////////
//procedure of delhosrse //
//////////////////////////////

procedure delhorse(i,j:integer);
var
successor:successorarray;
m,count,n:integer;
q:node;
ff:boolean;
begin
ff:=false;
select(i,j,count,successor);
if count=0
then delhorseok[i][j]:=false;
if count=1
then begin
board[i][j]:=0;
q:=successor[count];
delhorseok[q.x][q.y]:=false;
end;
if count>1
then begin
board[i][j]:=0;
for m:=1 to count do
begin
q:=successor[m];
if delhorseok[q.x][q.y]=false
then begin
for n:=m to count-1 do
successor[n]:=successor[n+1];
dec(count);
ff:=true;
end;
end;
if ff
then for m:=1 to count do
begin
q:=successor[m];
if delhorseok[q.x][q.y]
then delhorse(q.x,q.y);
end
else begin
delhorseok[successor[count].x][successor[count].y]:=false;
for m:=1 to count do
begin
q:=successor[m];
if not delhorseok[q.x][q.y]
then
delhorseok[successor[count].x][successor[count].y]:=true
else
delhorse(q.x,q.y);
end;
end;
end;
end;
////////////////////////////////
// main part of program //
///////////////////////////////

begin
for i:=1 to col do
for j:=1 to line do
begin
board[i][j]:=1;
delhorseok[i][j]:=true;
end;
board[1][1]:=0; board[2][2]:=0; board[1][3]:=0;
board[8][8]:=0; board[9][9]:=0; board[9][3]:=0;
board[9][10]:=0; board[8][9]:=0; board[9][8]:=0;
board[1][10]:=0; board[2][9]:=0; board[3][10]:=0;
for i:=1 to col do
for j:=1 to line do
if delhorseok[i][j] and (board[i][j]=1)
then delhorse(i,j);
for j:=line downto 1 do
begin
for i:=1 to col do
if delhorseok[i][j]
then write('O ')
else write('# ') ;
writeln;
writeln;
end;
readln;
end.
andrew80 2001-11-27
  • 打赏
  • 举报
回复
回朔是对的,不要考虑别马腿.
摆了一个马后,下一个马的位置只有四个.

仅供参考:

program jumphouse;
const
n=5;
type
item=record
x,y:integer;
end;
var
visited:array [1..n,1..n] of boolean;
root:array [1..n*n] of item;
i,j,k,x,y:integer;
total:integer;
procedure print;
var
i:integer;
begin
total:=total+1;
for i:=1 to n*n do
write('(',root[i].x,',',root[i].y,')',' ');
writeln;
end;
procedure search(x,y:integer);
var
i,j:integer;
begin
if (x in [1..n]) and (y in [1..n]) and (not visited[x,y])
then begin
k:=k+1;
root[k].x:=x;
root[k].y:=y;
visited[x,y]:=true;
if k=n*n
then print
else begin
for i:=1 to 2 do
begin
search(x+i,y+3-i);
search(x+i,y-3+i);
search(x-i,y+3-i);
search(x-i,y-3+i);
end;
end;
k:=k-1;
visited[x,y]:=false;
end;
end;
begin
total:=0;
for i:=1 to n do
for j:=1 to n do
visited[i,j]:=false;
k:=0;
search(1,1);
writeln(total);
end.
hubinjushi 2001-11-26
  • 打赏
  • 举报
回复
我认说简单也简单,如果考虑别腿的话,很显然,将整个棋盘都放马,就是极小满覆盖了,because当去掉任意一个马以后,对于这个位置,剩下的马都没法吃掉它(都给别死了)。

andrew80 2001-11-26
  • 打赏
  • 举报
回复
黄河吧!
幸会幸会
hubinjushi 2001-11-26
  • 打赏
  • 举报
回复
你不是作五子棋吗
williamf 2001-11-26
  • 打赏
  • 举报
回复
兄弟,工大的吗?我也做这一题

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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