八皇后问题

//遇到难题了 八皇后问题的、回溯算法;不会,只能网上搜来看看了;只是觉得python语言好精简啊

问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n1×n1,而皇后个数也变成n2。而且仅当 n2 = 1 或 n1 ≥ 4 时问题有解。

C/C++程序:

#include<iostream>
using namespace std;
static int gEightQueen[8] = { 0 }, gCount = 0;
void print()//输出每一种情况下棋盘中皇后的摆放情况
{
    for (int i = 0; i < 8; i++)
    {   
        int inner;
        for (inner = 0; inner < gEightQueen[i]; inner++)
            cout << "0";
            cout <<"#";
        for (inner = gEightQueen[i] + 1; inner < 8; inner++)
            cout << "0";
        cout << endl;
    }
    cout << "==========================\n";
}
int check_pos_valid(int loop, int value)//检查是否存在有多个皇后在同一行/列/对角线的情况
{
    int index;
    int data;
    for (index = 0; index < loop; index++)
    {
        data = gEightQueen[index];
        if (value == data)
            return 0;
        if ((index + data) == (loop + value))
            return 0;
        if ((index - data) == (loop - value))
            return 0;
    }
    return 1;
}
void eight_queen(int index)
{
    int loop;
    for (loop = 0; loop < 8; loop++)
    {
        if (check_pos_valid(index, loop))
        {
            gEightQueen[index] = loop;
            if (7 == index)
            {
                gCount++, print();
                gEightQueen[index] = 0;
                return;
            }
            eight_queen(index + 1);
            gEightQueen[index] = 0;
        }
    }
}
int main(int argc, char*argv[])
{
    eight_queen(0);
    cout << "total=" << gCount << endl;
    return 0;
}


java程序:

public class Queen{
//同栏是否有皇后,1表示有
private int[] column;
//右上至左下是否有皇后
private int[] rup;
//左上至右下是否有皇后
private int[] lup;
//解答
private int[] queen;
//解答编号
private int num;
public Queen(){
column=new int[8+1];
rup=new int[(2*8)+1];
lup=new int[(2*8)+1];
for(int i=1;i<=8;i++)
column[i]=0;
for(int i=1;i<=(2*8);i++)
rup[i]=lup[i]=0;  //初始定义全部无皇后
 
queen=new int[8+1];
}
 
public void backtrack(int i){
if(i>8){
showAnswer();
}else{
for(int j=1;j<=8;j++){
if((column[j]==0)&&(rup[i+j]==0)&&(lup[i-j+8]==0)){
//若无皇后
queen[i]=j;
//设定为占用
column[j]=rup[i+j]=lup[i-j+8]=1;
backtrack(i+1);  //循环调用
column[j]=rup[i+j]=lup[i-j+8]=0;
}
}
}
}
 
protected void showAnswer(){
num++;
System.out.println("\n解答"+num);
 
for(int y=1;y<=8;y++){
for(int x=1;x<=8;x++){
if(queen[y]==x){
System.out.print("Q");
}else{
System.out.print(".");
}
}
 
System.out.println();
}
}
 
public static void main(String[]args){
Queen queen=new Queen();
queen.backtrack(1);
}
}

python 语言:

def queen(A,cur=0):
    if cur == len(A): print A ;return
    for col in range(len(A)):
        A[cur],flag = col,True
        for row in range(cur):
            if A[row] == col or abs(col-A[row])==cur - row:flag=False;break
        if flag:queen(A,cur+1)
queen([None]*8)



图形实现:

//eigqueprob.h
#include "stdio.h"
#define N 8 // N 表示皇后的个数 用来定义答案的结构体
typedef struct
{
    int line; // 答案的行号  
    int row; // 答案的列号 
}ANSWER_TYPE;// 用来定义某个位置是否被占用 
 
typedef enum
{
    notoccued = 0, // 没被占用  occued = 1 // 被占用 
    occued = 1
}IFOCCUED;// 该列是否已经有其他皇后占用 
 
 
IFOCCUED rowoccu[N];// 左上-右下对角位置已经有其他皇后占用 
IFOCCUED LeftTop_RightDown[2 * N - 1];// 右上-左下对角位置已经有其他皇后占用
IFOCCUED RightTop_LefttDown[2 * N - 1];// 最后的答案记录 
ANSWER_TYPE answer[N];
 
 
/* 寻找下一行占用的位置 */
void nextline(int LineIndex)
{
    static int asnnum = 0; /* 统计答案的个数 */
    int RowIndex = 0; /* 列索引 */
    int PrintIndex = 0;/* 按列开始遍历 */
    for (RowIndex = 0; RowIndex < N; RowIndex++)
    {
        /* 如果列和两个对角线上都没有被占用的话,则占用该位置 */
        if ((notoccued == rowoccu[RowIndex]) && (notoccued == LeftTop_RightDown[LineIndex - RowIndex + N - 1]) && (notoccued == RightTop_LefttDown[LineIndex + RowIndex]))
        {
            /* 标记已占用 */
            rowoccu[RowIndex] = occued;
            LeftTop_RightDown[LineIndex - RowIndex + N - 1] = occued;
            RightTop_LefttDown[LineIndex + RowIndex] = occued;
            /* 标记被占用的行、列号 */
            answer[LineIndex].line = LineIndex; answer[LineIndex].row = RowIndex;
            /* 如果不是最后一行,继续找下一行可以占用的位置 */
            if ((N - 1) > LineIndex) {
                nextline(LineIndex + 1);
            }
            /* 如果已经到了最后一行,输出结果 */
            else
            {
                asnnum++;
                printf("\nThe %dth answer is :", asnnum);
                for (PrintIndex = 0; PrintIndex<N; PrintIndex++)
                {
                    printf("(%d,%d) ", answer[PrintIndex].line + 1, answer[PrintIndex].row + 1);
                }
                /* 每10个答案一组,与其他组隔两行 */
                if ((asnnum % 10) == 0)
                    printf("\n\n");
            }
            /* 清空占用标志,寻找下一组解 */
            rowoccu[RowIndex] = notoccued;
            LeftTop_RightDown[LineIndex - RowIndex + N - 1] = notoccued;
            RightTop_LefttDown[LineIndex + RowIndex] = notoccued;
        }
    }
}
int main()
{
    int i = 0;
    /* 调用求解函数*/
    nextline(i);
    /* 保持屏幕结果*/
    getchar();
    return 1;
}


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello689

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值