zoukankan      html  css  js  c++  java
  • 八皇后问题

    八皇后问题。是一个古老而著名的问题。是回溯算法的典型案例。

    该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击。即随意两个皇后都不能处于同一行、同一列或同一斜线上。问有多少种摆法。 高斯觉得有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解。后来有人用图论的方法解出92种结果。

    计算机发明后。有多种计算机语言能够解决此问题。

    八皇后问题


    解题思路:

    我们按行推断。从上到下,假设某个位置有效,则置“Q”。无效则置“.”。基本的问题就是推断该位置是否有效。是否是危急位置(会产生冲突)。我们要推断本行、本列、此斜线上都没有皇后存在,此时才干够在这个位置上放置皇后。代码例如以下:

    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    const int queenNum=8;
    int count=0;
    vector<vector<string> > solveNQueens(int n);
    void Nqueen(int row,int n,vector<vector<string>> &chess);
    bool notDanger(int row,int j,vector<vector<string>> chess);
    void main()
    {
    	vector<vector<string>> chess;
    	vector<string> temp(queenNum,".");
    	for (int i=0;i<queenNum;i++)
    	{
    		chess.push_back(temp);
    	}
    	chess= solveNQueens(queenNum);
    }
    vector<vector<string> > solveNQueens(int n) {
    	vector<vector<string>> chess;
    	vector<string> temp(queenNum,".");
    	for (int i=0;i<queenNum;i++)
    	{
    		chess.push_back(temp);
    	}
    	Nqueen(0,queenNum,chess);
    	cout<<"共同拥有:"<<count<<"种分布"<<endl;
    	return chess;
    }
    
    void Nqueen(int row,int n,vector<vector<string>> &chess)
    {
    	vector<vector<string>> chess2;
    	chess2=chess;
    	if (queenNum==row)
    	{
    		cout<<"第"<<count+1<<"种分布"<<endl;
    		for (int i=0;i<queenNum;i++)
    		{
    			for (int j=0;j<queenNum;j++)
    			{
    				cout<<chess2[i][j];
    			}
    			cout<<endl;
    		}
    		cout<<endl<<endl;
    		count++;
    	}
    	else
    	{
    		for (int j=0;j<n;j++)
    		{
    			if (notDanger(row,j,chess))//推断是否危急
    			{
    				for (int i=0;i<queenNum;i++)
    				{
    					chess2[row][i]=".";
    				}
    				chess2[row][j]="Q";	
    				Nqueen(row+1,n,chess2);
    			}
    		}
    	}
    	
    }
    
    bool notDanger(int row,int j,vector<vector<string>> chess)
    {
    	bool flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
    	//推断列方向
    	for (int i=0;i<queenNum;i++)
    	{
    		if (chess[i][j]!=".")
    		{
    			flag1=1;
    			break;
    		}
    	}
    	//推断左上方
    	for (int i=row,k=j;i>=0&&k>=0;i--,k--)
    	{
    		if (chess[i][k]!=".")
    		{
    			flag2=1;
    			break;
    		}
    	}
    	//推断左下方
    	for (int i=row,k=j;i<queenNum&&k>=0;i++,k--)
    	{
    		if (chess[i][k]!=".")
    		{
    			flag3=1;
    			break;
    		}
    	}
    	//推断右上方
    	for (int i=row,k=j;i>=0&&k<queenNum;i--,k++)
    	{
    		if (chess[i][k]!=".")//
    		{
    			flag4=1;
    			break;
    		}
    	}
    	//推断右下方
    	for (int i=row,k=j;i<queenNum&&k<queenNum;i++,k++)
    	{
    		if (chess[i][k]!=".")
    		{
    			flag5=1;
    			break;
    		}
    	}
    	if (flag1||flag2||flag3||flag4||flag5)
    	{
    		return false;
    	}
    	else
    		return true;
    }
    


    代码中我们能够更改queueNum的值来计算n皇后的问题。

  • 相关阅读:
    P1495 曹冲养猪
    luoguP4281[AHOI2008]紧急集合 / 聚会
    NOIP1997 代数表达式
    luogu P3709大爷的字符串题
    luoguP3912 素数个数
    POJ 1065 Wooden Sticks
    POJ 1063 Flip and Shift
    POJ 1062 昂贵的聘礼
    POJ 1003 Hangover
    POJ 1001 Exponentiation
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6818168.html
Copyright © 2011-2022 走看看