您的位置:首页 > 产品设计 > UI/UE

Eight Queen

2017-12-19 21:46 92 查看

八皇后问题

代码

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <cmath>

using namespace std;
int p[8][8];                // 棋盘数组
int cnt;                    //记录解的个数

//判断(r,c)位置能否放置棋子,能,返回true,不能返回false
//因为是从第一行开始往下放棋子,所以只需要判断r行之前的行中有没有棋子使得(r,c)不可落子即可
bool can(int r, int c){
for (int i=0; i<r; i++){        //判断同一列中是否有棋子,有则返回false
if (p[i][c] == 1)
return false;
}

int rr;                         //临时纵坐标(行数)
int rc;                         //临时横坐标(列数)

for (int i=1; i<=r; i++){       //判断(r,c)左上方是否有棋子使(r,c)处不可落子
rr = r-i;
rc = c-i;

if (rr>=0 && rc>=0){
if (p[rr][rc] == 1)
return false;
}
}

for (int i=1; i<=r; i++){       //判断(r,c)右上方是否有棋子使(r,c)处不可落子
rr = r-i;
rc = c+i;

if (rr>=0 && rc<=7){
if (p[rr][rc] == 1)
return false;
}
}

return true;
}

//显示各个结果
void show(){
for (int i=0; i<8; i++){
for (int j=0; j<8; j++){
printf("%d ", p[i][j]);
}
printf("\n");
}
}

//dfs遍历,参数r为落子的纵坐标(行)
void dfs(int r){

if (r == 7){                        //若这是最后一行,则在此行中找到可以落最后一个棋子的位置
for (int j=0; j<8; j++){
if (can(r, j)){
p[r][j] = 1;            //将该位置设为有棋子
cnt++;                  //解的个数加一
printf("%d\n", cnt);    //输出解的编号
show();                 //显示改解
p[r][j] = 0;            //回溯,将该位置设为没有棋子
}
}
}else{
for (int j=0; j<8; j++){        //若不是最后一行,则在该行中找到可已落子的位置,再从下一行开始执行dfs()
if (can(r, j)){
p[r][j] = 1;            //将该位置设为有棋子
dfs(r+1);               //到下一行,调用dfs(r+1)
p[r][j] = 0;            //回溯,将该位置设为没有棋子
}
}
}
}
int main()
{
memset(p, 0, sizeof(p));
dfs(0);                             //从第一行开始搜索
printf("cnt = %d\n", cnt);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dfs 回溯算法