C++搜索N皇后问题
推薦刷題網站:http://47.108.154.71/http://47.108.154.71/
N皇后問題題目:
在N*N(1<N<=9)的棋盤上放置N個皇后而彼此不受攻擊(即在棋盤的任一行,任一列和任一對角線上不能放置2個皇后),編程求解所有的擺放方法。
?[輸入格式]?
一個整數n(1<n<=9)
[輸出格式]
若有解,輸出若干行,每行n個數,依次表示第i個皇后的列號
若無解,輸出 “no”
[輸入樣例]
4
[輸出樣例]
2 ? ?4 ? ?1 ? ?3
3 ? ?1 ? ?4 ? ?2
解題思路:
N皇后問題當中有個其妙的規律——各個斜邊上的下標差或和相等。
由上圖各位讀者老爺可以發現斜邊上的規律,當然我只列舉了其中一條,其實其于斜邊都有這種規律,老爺們可以自己去找找。?
但是,有沒有想過,就這些規律可以有什么作用?
好問題,讓我們再回顧一下題目要求即在棋盤的任一行,任一列和任一對角線上不能放置2個皇后
判斷任意一行,任意一列和任意對角線上的皇后我們生活中一眼看過去就行了但是,電腦想要識別可不能像我們這樣,所以我們找的這個規律就是用來當做行列的“身份證”的。
這樣做的目的:通過行,列,對角線上的固定差值,來進行判斷記錄。
例如黑色線段上的格子,下標的和無論如何都是6。其他的斜邊也都有自己一個固定的值,這就像是身份證一樣,獨一無二,所以判斷時,只需判斷重復“身份證”沒有,即可實現不重復皇后的要求
可問題在于,有些斜邊差回事負數,但是C++中下標最下是0,負數是違法的,為了避免這種情況可以統一給所有計算差或和時統一加上N,或者是7,畢竟圖最大也就是7,(0,1,2,3,4,5,6,7,八個數)
代碼實現
#include <bits/stdc++.h>//萬能頭文件可概括全部的頭文件 using namespace std; long long sum=0;//sum是拿來計數的所以初始值是0. bool a[100],c[100],d[100]; int b[100],n; int print()//這里是定義了一個輸出函數 {sum++;//用來記錄方案數量 for(int i=1;i<=n;++i)cout<<b[i]<<" ";//輸出當前的全部方案 cout<<endl;//換行 } int search(int i) {for(int j=1;j<=n;++j){if(a[j]==0&&c[i+j]==0&&d[i-j+7]==0)/*當畫一個6*6的格子再根據題目進行分析時可發現: 每行每列每個斜邊都有固定的差或者和,可以利用這個進行判斷,存進數組 輸出回溯……但有些數字差會是負數,且有的行列的差或和會跟其他行列的差或和 重復。所以就將全部數都加上一個7或n,在既保證不是負數也不重復情況下,又保證每行每列每個斜邊上差跟和不一樣這樣就十分容易。 注:畫圖理解更佳*/ {b[i]=j;//存放 。 a[j]=1;//等于1不再使用 。 c[i+j]=1;d[i-j+7]=1;if(i==n)//在滿了不再有其他擺放方法時就將當前的方案輸出 。 print();elsesearch(i+1);a[j]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。 c[i+j]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。d[i-j+7]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。}} } int main() {cin>>n;search(1);if(sum==0)cout<<"no";//如果無解 一個方案都沒有 就按照題目要求輸出no。 return 0; }游客有好版
#include <bits/stdc++.h>//萬能頭文件可概括全部的頭文件 ? ? ? ??
using namespace std;
long long sum=0;//sum是拿來計數的所以初始值是0.?
bool a[100],c[100],d[100];?
int b[100],n;
int print()//這里是定義了一個輸出函數?
{
? ? sum++;//用來記錄方案數量?
? ? for(int i=1;i<=n;++i)cout<<b[i]<<" ";//輸出當前的全部方案 ?
? ? cout<<endl;//換行?
}
int search(int i)
{
? ? for(int j=1;j<=n;++j)
? ? {
? ? ? ? if(a[j]==0&&c[i+j]==0&&d[i-j+7]==0)
?? ??? ?/*當畫一個6*6的格子再根據題目進行分析時可發現:?
?? ??? ?每行每列每個斜邊都有固定的差或者和,可以利用這個進行判斷,存進數組?
?? ??? ?輸出回溯……但有些數字差會是負數,且有的行列的差或和會跟其他行列的差或和?
?? ??? ?重復。所以就將全部數都加上一個7或n,在既保證不是負數
?? ??? ?也不重復情況下,又保證每行每列每個斜邊上差跟和不一樣
?? ??? ?這樣就十分容易。?
?? ??? ?
?? ??? ?注:畫圖理解更佳*/?
? ? ? ? {
? ? ? ? ? ? b[i]=j;//存放 。?
? ? ? ? ? ? a[j]=1;//等于1不再使用 。?
? ? ? ? ? ? c[i+j]=1;
? ? ? ? ? ? d[i-j+7]=1;
? ? ? ? ? ? if(i==n)//在滿了不再有其他擺放方法時就將當前的方案輸出 。?
? ? ? ? ? ? ? ? print();
? ? ? ? ? ? else
? ? ? ? ? ? ? ? search(i+1);
? ? ? ? ? ? a[j]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。?
? ? ? ? ? ? c[i+j]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。
? ? ? ? ? ? d[i-j+7]=0;//回溯 撤回上次的記錄 恢復保存結果之前的狀態。
? ? ? ? }
? ? }
}
int main()
{
? ? cin>>n;
? ? search(1);
? ? if(sum==0)cout<<"no";//如果無解 一個方案都沒有 就按照題目要求輸出no。?
? ? return 0; ?
}
給個贊吧,謝謝啦…………
總結
以上是生活随笔為你收集整理的C++搜索N皇后问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决office的PPT和WPS的PPT
- 下一篇: 泛型编程和STL基础学习(C++)(未完