码迷,mamicode.com
首页 > 其他好文 > 详细

回溯法第3题—n皇后问题

时间:2014-08-12 21:46:54      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   for   ar   问题   

[问题描述]

在一个国际棋盘上,放置n个皇后(n<10),使她们相互之间不能进攻。求出所有布局。

输入:n

输出:每行输出一种方案,每种方案顺序输出皇后所在的列号,每个数之间用空格隔开。

[样例输入]

4

[样例输出]

2 4 1 3
2 1 4 2

[问题分析]

我想这大概是回溯法最经典的一个问题了吧,开一个函数判断一下当前位置是否能放即可。

这里有一个小技巧,就是对皇后进行编号,对应着数组的下标,就可以很容易的满足第一个条件——所有皇后不能在同一行上。

然后数组元素则代表皇后所在的列数,满足第二个条件——所有皇后不能在同一列上,就有a[k]<>a[i](for i:=1 to k-1)

条件三:所有皇后不能出现在对角线上;

这里面所谓的对角线是棋盘单个矩形方格的对角线,即斜率为1或-1的直线。

由数学知识可以得到当斜率为1时,有:a[i]-a[k]=i-k;斜率为-1时,有:a[i]-a[k]=k-i;

由此可以得到总的公式:abs(a[i]-a[k])=abs(i-k)

分析完了,上代码,下面是我写的(代码很短,最喜欢的就是短代码)

//刚开始我感觉有些难理解,于是写了很多注释
var a:array[1..100] of integer;//用行号作为下标编号,避免行号重复
    n:integer;
function can(k,i:integer):boolean;//i代表第k行的第i列
var j:integer;
begin
   for j:=1 to k-1 do
    if (abs(a[j]-i)=abs(j-k))or(i=a[j]) then exit(false);
    // (i=a[j])表示k和j在同一列上,(abs(a[j]-i)=abs(j-k))表示k和j在对角线上
   exit(true);
end;
procedure try(k:integer);
 var i:integer;
begin
  if k>n then
    begin 
     for i:=1 to n do write(a[i], );writeln;end
   else
     for i:=1 to n do//从第k行的每一列搜索
      if can(k,i) then//如果k可以放在第i列上
        begin
          a[k]:=i;
          try(k+1);//搜索下一行
        end;
end;
begin
 readln(n);
 try(1);//从第一行开始一行一行搜索
end.

下面是标准程序

var
  a:array  [1..100]  of  integer;
  n,p:integer;
function  find(k,i:integer):boolean;
var    j:integer;
       yes:boolean;
begin
  yes:=true;
 for  j:=1  to  k-1  do
   if  (abs(a[j]-i)=abs(j-k))or(i=a[j])  then  yes:=false;
 find:=yes
end;
procedure print;
var  i:integer;
begin
  p:=1;
  for  i:=1  to  n  do
    write(a[i]:5);
  writeln
end;
procedure  try(k:integer);
var  i:integer;
begin
 if  k>n  then  print
  else
    for i:=1  to  n  do
        if  find(k,i)  then
          begin
            a[k]:=i;
            try(k+1);
          end;
    if (p=0)and(k=1)and(a[k]=3) then writeln(no solute!)
end;
begin
assign(input,word.in);
reset(input);
assign(output,word.out);
rewrite(output);
p:=0;
readln(n);
try(1);
end.

关于n皇后的其他问题,可以参考百度百科http://baike.baidu.com/view/698719.htm

通过看标准程序,发现它总是运用许多的过程和函数,看起来思路比较清晰。这启示我们要学会写模块化的程序,把大问题转化为许多小问题,然后逐个击破。

回溯法第3题—n皇后问题,布布扣,bubuko.com

回溯法第3题—n皇后问题

标签:style   blog   http   color   io   for   ar   问题   

原文地址:http://www.cnblogs.com/cuichen/p/3908433.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!