❶ java八皇後問題
希望我解釋的你能明白:
把棋盤看成二維方陣,行從上到下編號0-7(就是i),列從左到右編號0-7(就是j),這樣棋盤上每個點都可以表示為(i,j)
從鍵盤的右上角(0,7)到左下角(7,0)的對角線,以及這條線的平行線,就是反對角線,也就是這個程序里的undiagonal。顯然這個反對角線上任意2點(i1,j1)和(i2,j2)都滿足i1+j1=i2+j2.因為i+j可能的取值范圍是從0到14,所以把這個數組的長度定義為16(事實上15就可以了)
從鍵盤的左上角(0,0)到右下角(7,7)的對角線以及平行線,就是對角線,就是diagonal。同理,這個對角線及其平行線上任意2點都滿足i1-i2=j1-j2.i-j的范圍是-7到7,為了避免出現負數,程序里在這里+7,也是一個長度為16的數組(還是15就夠了)
程序一開始的時候,i=j=0,所有的安全標識都是true,所以(0,0)這個點會被輸出。這時,把diagonal【7】置為false。因為(1,1),(2,2)等等這些點都和(0,0)在一條對角線上(因為0-0+7=1-1+7=2-2+7),所以把這些點的對應的diagonal都置為false,也就是把diagonal【7】置為false
並且把undiagonal【0】也置為false,但是因為undiagonal【0】對應的元素只有(0,0)(因為只有0+0=0),所以這個對這一步沒什麼影響。
然後一點點遞推,回溯,步驟就是這樣。希望你看得懂,如果不明白的話給我發消息吧
❷ JAVA中八皇後問題演算法和流程圖。要求用回溯法,求大神解答,在線等如果有代碼就完美了
[cpp] view plainprint?
//--------------------------------------
//利用函數遞歸,解決八皇後問題
//
// zssure 2014-03-12
//--------------------------------------
#include <stdio.h>
#include <cmath>
int count=0;//全局計數變數
/*--------------------四個皇後----------------------*/
//#define QUEEN_NUM 4
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0 };
/*--------------------五個皇後----------------------*/
//#define QUEEN_NUM 5
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0 };
/*--------------------六個皇後----------------------*/
//#define QUEEN_NUM 6
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0
// };
/*--------------------七個皇後----------------------*/
//#define QUEEN_NUM 7
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0
// };
/*--------------------八個皇後----------------------*/
#define QUEEN_NUM 8
int label[QUEEN_NUM][QUEEN_NUM]={0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0};
void FillChessbox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n))//對角區域填充
{
if(label[i][j]==0)
label[i][j]=num;
}
int i=0,j=0;
while(i<QUEEN_NUM)//行填充
{
if(label[i][n]==0)
label[i][n]=num;
++i;
}
while(j<QUEEN_NUM)//列填充
{
if(label[m][j]==0)
label[m][j]=num;
++j;
}
}
void ClearChessBox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n) && label[i][j]==num)
label[i][j]=0;
int i=0,j=0;
while(i<QUEEN_NUM)
{
if(label[i][n]==num)
label[i][n]=0;
++i;
}
while(j<QUEEN_NUM)
{
if(label[m][j]==num)
label[m][j]=0;
++j;
}
}
void AllClear()
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
label[i][j]=0;
}
void PrintResult()
{
for(int i=0;i<QUEEN_NUM;++i)
{
for(int j=0;j<QUEEN_NUM;++j)
printf("%d ",label[i][j]);
printf("\n");
}
}
bool EightQueen(int n/*皇後個數*/,int c/*已經放置的皇後個數*/)
{
//static int count=0;
//小於3x3的棋盤是無解的
if(n<4)
return false;
for(int i=0;i<n;++i)
{
if(label[c-1][i]==0)//存在可以放置第c個皇後的位置
{
label[c-1][i]=c+1;
if(c==n)/*已經放置完畢所有的皇後*/
{
++count;
PrintResult();
printf("**************************\n");
ClearChessBox(c-1,i,c+1);
//AllClear();
return true;
}
FillChessbox(c-1,i,c+1);
EightQueen(n,c+1);
ClearChessBox(c-1,i,c+1);
/*-------------------------------------------------------------------------------------------------------------------------
// 現場恢復,無論下一個皇後是否順利放置,都應該恢復現場。原因是
//
// 如果下一個皇後放置失敗,那麼自然應該將本次放置的皇後去除,重新放置,所以需要進行現場恢復(即回溯);
// 如果下一個皇後放置成功,意味著本次放置已經滿足條件,是一個解,此時需要恢復現場,進行下一次的重新放置,尋找下一個解。
//
//------------------------------------------------------------------------------------------------------------------------*/
//if(!EightQueen(n,c+1))
// ClearChessBox(c-1,i,c+1);
}
}
return false;
}
int main()
{
EightQueen(QUEEN_NUM,1);
printf("%d\n",count);
return 0;
}
❸ java:八皇後問題解題思路
遞歸:
首先每一行放置均會循環,也就是每一行的皇後都會被依次放置在8個位置上;
1)第一行在第一個位置上放置1枚皇後;
2)第二行在第一個位置上放置皇後,如果與已有的皇後不在一條直線上,則進入下一行,否則位置+1;
3)餘下幾行均依照步驟2)的方法進行放置,當最後一行放置好,列印輸出;
可以寫個函數,EightQueen(int
n,
int
*Pos),其中n表示第幾行,Pos指向一個數組,Pos[i]=j表示第i行的位置是j;EightQueen(int
n,
int
*Pos)從n=1開始遞歸,到n=8遞歸結束。
代碼就不寫了,沒寫過java,寫不來
❹ 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);}}
❺ 八皇後問題的java代碼。
boolean[] diagonal = new boolean[16]; // 對角線安全標志
boolean[] undiagonal = new boolean[16]; // 反對角線安全標志
用上兩個判斷是否能放置棋子
在 n 行 n 列的國際象棋棋盤上,最多可布n個皇後。
若兩個皇後位於同一行、同一列、同一對角線上,
則稱為它們為互相攻擊。
n皇後問題是指找到這 n 個皇後的互不攻擊的布局。
n 行 n 列的棋盤上,主次對角線各有2n-1條。
利用行號i和列號j計算
主對角線編號k的方法是k = n+i-j-1;
計算次對角線編號k的方法是k = i+j
你主要是演算法有些模糊罷了,現在我怕我說的不好將你弄的越來越混亂所以給你個叫形象的若是還不明白,call me
package 網路;
//演示程序:n個皇後問題
import java.io.*;
/*
在 n 行 n 列的國際象棋棋盤上,最多可布n個皇後。
若兩個皇後位於同一行、同一列、同一對角線上,
則稱為它們為互相攻擊。
n皇後問題是指找到這 n 個皇後的互不攻擊的布局。
n 行 n 列的棋盤上,主次對角線各有2n-1條。
利用行號i和列號j計算
主對角線編號k的方法是k = n+i-j-1;
計算次對角線編號k的方法是k = i+j
*/
//"n個皇後問題"之類定義
public class cQueen {
int n; //皇後問題的大小
int col[]; //數組,各列上有無皇後(0,1)
int md[]; //數組,各主對角線有無皇後(0,1)
int sd[]; //數組,各次對角線有無皇後(0,1)
int q[]; //數組,第i行上皇後在第幾列(0,n-1)
int Q; //已布皇後數,計數
int r; //n皇後問題的解的組數
//構造函數 n皇後問題的初始化
public cQueen(int m) {
n=m;Q=0;r=0;
col=new int[n];
md=new int[2*n-1]; //初始化0
sd=new int[2*n-1];
q=new int[n];
}
//函數:列印棋盤
public void showBoard() {
int i,j;
for(i=0;i<n;i++) {
for(j=0;j<n;j++)
if(q[i]==j) System.out.print("1 ");
else System.out.print("0 ");
System.out.println();
}
r++; //解的組數
System.out.println("---------------");
}
//求解n皇後問題
/*
此函數試圖在n*n的棋盤的第i行上放一個皇後,
若找到可以放的位置,就遞歸調用自身試圖在i+1行
放另一個皇後,若第i行是最後一行,則列印棋盤。
*/
public void resolve(int i) {
int j;
// 在第i行給定後檢查棋盤上的每一列
for(j=0;j<n;j++) {
//如果在第i行的第j列可以布放皇後
if(col[j]==0&&md[n+i-j-1]==0&&sd[i+j]==0){
Q++;q[i]=j; //布放皇後,第i行皇後在第幾列
// 標記新布皇後的攻擊范圍
col[j]=md[n+i-j-1]=sd[i+j]=1;
// 如果已經布了n個皇後(得到了一組解),
// 把棋盤(解)列印出來。
if(Q==n) showBoard();
// 否則,遞歸。在第i行第j列布放皇後的前提下,
//試探下一行(i+1行)在哪一列布皇後?
else if(i<n-1) resolve(i+1);
else resolve(0); //因為約定起始行可以任選
//移除在第i行的第j列新布的皇後,
//並消除所標記的攻擊范圍,為回溯作準備。
Q--; q[i]=0;
col[j]=md[n+i-j-1]=sd[i+j]=0;
//試探在第i行的第j+1列新布皇後的方案(新解)
}
} //下一列,j循環
//對於給定的行,列掃描完畢後,從這里回溯。
}
//輸出解的個數
public void HowMany() {
System.out.println(n+"皇後問題共有解"+r+"組。");
}
//主方法main()
public static void main(String []args) {
//定義一個8皇後問題(有92組解)
cQueen Q1=new cQueen(8); //大於10,你的微機可能要死機!
//第一個皇後可以在任意一行布放
Q1.resolve(0); //參數在0到n-1之間任選
Q1.HowMany();
}
} //類Queen定義結束
關於看代碼的人人都知道的小技巧,最小試探法來輸出結果進行比較和分析
❻ 請教JAVA大神,八皇後問題代碼
publicclassQueen{
//同欄是否有皇後,1表示有
privateint[]column;
//右上至左下是否有皇後
privateint[]rup;
//左上至右下是否有皇後
privateint[]lup;
//解答
privateint[]queen;
//解答編號
privateintnum;
publicQueen(){
column=newint[8+1];
rup=newint[(2*8)+1];
lup=newint[(2*8)+1];
for(inti=1;i<=8;i++)
column[i]=1;
for(inti=1;i<=(2*8);i++)
rup[i]=lup[i]=1;
queen=newint[8+1];
}
publicvoidbacktrack(inti){
if(i>8){
showAnswer();
}else{
for(intj=1;j<=8;j++){
if((column[j]==1)&&(rup[i+j]==1)&&
(lup[i-j+8]==1)){
queen[i]=j;
//設定為佔用
column[j]=rup[i+j]=lup[i-j+8]=0;
backtrack(i+1);
column[j]=rup[i+j]=lup[i-j+8]=1;
}
}
}
}
protectedvoidshowAnswer(){
num++;
System.out.println(" 解答"+num);
for(inty=1;y<=8;y++){
for(intx=1;x<=8;x++){
if(queen[y]==x){
System.out.print("Q");
}else{
System.out.print(".");
}
}
System.out.println();
}
}
publicstaticvoidmain(String[]args){
Queenqueen=newQueen();
queen.backtrack(1);
}
}
❼ 求:N皇後問題的JAVA代碼
這是我剛寫的程序
程序如下:
import java.util.*;
import java.io.*;
public class NQueens {
public static void print(int a[]){//輸出解
//int b[]=a;
for(int i=1,j=a.length-1;i<a.length;i++,j--){
System.out.print(a[i]+"--");
//b[j]=a[i];//記錄對稱解
}
a[0]++;
System.out.println();
/*for(int i=1;i<b.length;i++){
System.out.print(b[i]+"--");
}
a[0]++;
System.out.println();*/
}//print
public static void main (String[] args) throws IOException{
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Please input the number of queens:");
int n=Integer.parseInt(bf.readLine());
System.out.println("n="+n);
System.out.println("start...");
long start=new Date().getTime();
int a[]=new int[n+1];
for(int i=0;i<n+1;i++) a[i]=0;//初始化棋盤
for(int cTemp=1,rTemp=1,j=1;cTemp<=n;cTemp++){//(n+1)/2
a[1]=cTemp;//第一個皇後依次放在每一列上面
for(rTemp=1,j=1;rTemp+1<=n;){
if(j>n&&j!=1) {j=a[rTemp]+1;rTemp--;continue;}//
a[rTemp+1]=j;//第rTemp+1個皇後試著放在第j列
if(a[1]==n&&a[2]==n) break;//全部訪問完畢
//System.out.println("Aa[rTemp+1]"+(rTemp+1)+":"+a[rTemp+1]);//
int i;
for(i=1;i<rTemp+1;i++){//檢測是否與已放的皇後有沖突
if(a[i]==a[rTemp+1]||Math.abs(rTemp+1-i)==Math.abs(a[rTemp+1]-a[i])) {
//兩個皇後在同一列上或在同一對角線上,不行
//System.out.println("Ba[rTemp+1]"+(rTemp+1)+":"+a[rTemp+1]);//
//System.out.println("j:"+j);//
//System.out.println("i:"+i);//
break;
}
//System.out.println("break1");break;
}//for
if(i==rTemp+1) {//第rTemp+1個皇後可以放
rTemp++;
j=1;
//System.out.println("continue");//
if(rTemp==n) {NQueens.print(a);j=a[rTemp-1]+1;rTemp=rTemp-2;}//找到一個可行解
continue;
}
else if(j==n) {rTemp--;j=a[rTemp+1]+1;if(rTemp==1&&a[rTemp+1]>=n) break;else continue;}
//放完了,無解,回溯到上一個皇後
else if(j<n){j++;continue;}//還沒放完,繼續
else if(a[rTemp+1]==n) break;//
//if(j>n) {System.out.println("j>n,break2");break; }
//System.out.println("Ca[rTemp+1]:"+(rTemp+1)+":"+a[rTemp+1]);//
if(rTemp+1==n) break;
//System.out.println("break2");break;
}//for
if(rTemp==cTemp) continue;
//System.out.println("break3");break;
}//for
long end=new Date().getTime();
System.out.println("System runtime is "+(end-start)+" ms.");
System.out.println("The "+n+" queen problem's solution number is:"+a[0]);
System.out.println("end...");
}
}
❽ java八皇後問題的實驗報告
http://blog.itweb2.com/article.asp?id=140
*
* 8皇後問題:
*
* 問題描述:
* 在一個8×8的棋盤里放置8個皇後,要求每個皇後兩兩之間不相沖突
*(在每一橫列,豎列,斜列只有一個皇後)。
*
* 數據表示:
* 用一個 8 位的 8 進制數表示棋盤上皇後的位置:
* 比如:45615353 表示:
* 第0列皇後在第4個位置
* 第1列皇後在第5個位置
* 第2列皇後在第6個位置
* 。。。
* 第7列皇後在第3個位置
*
* 循環變數從 00000000 加到 77777777 (8進制數)的過程,就遍歷了皇後所有的情況
* 程序中用八進制數用一個一維數組 data[] 表示
*
* 檢測沖突:
* 橫列沖突:data == data[j]
* 斜列沖突:(data+i) == (data[j]+j) 或者 (data-i) == (data[j]-j)
*
* 好處:
* 採用循環,而不是遞規,系統資源佔有少
* 可計算 n 皇後問題
* 把問題線性化處理,可以把問題分塊,在分布式環境下用多台計算機一起算。
*
* ToDo:
* 枚舉部分還可以進行優化,多加些判斷條件速度可以更快。
* 輸出部分可以修改成棋盤形式的輸出
*
* @author cinc 2002-09-11
*
*/
public class Queen {
int size;
int resultCount;
public void compute ( int size ) {
this.size = size;
resultCount = 0;
int data[] = new int[size];
int count; // 所有可能的情況個數
int i,j;
// 計算所有可能的情況的個數
count = 1;
for ( i=0 ; i<size ; i++ ) {
count = count * size;
}
// 對每一個可能的情況
for ( i=0 ; i<count ; i++ ) {
// 計算這種情況下的棋盤上皇後的擺放位置,用 8 進制數表示
// 此處可優化
int temp = i;
for ( j=0 ; j<size ; j++ ) {
data [j] = temp % size;
temp = temp / size;
}
// 測試這種情況是否可行,如果可以,輸出
if ( test(data) )
output( data );
}
}
/*
* 測試這種情況皇後的排列是否可行
*
*/
public boolean test( int[] data ) {
int i,j;
for ( i=0 ; i<size ; i++ ) {
for ( j=i+1 ; j<size ; j++ ) {
// 測試是否在同一排
if ( data == data[j] )
return false;
// 測試是否在一斜線
if ( (data+i) == (data[j]+j) )
return false;
// 測試是否在一反斜線
if ( (data-i) == (data[j]-j) )
return false;
}
}
return true;
}
/*
* 輸出某種情況下皇後的坐標
*
*/
public void output ( int[] data ) {
int i;
System.out.print ( ++resultCount + ": " );
for ( i=0 ; i<size ; i++ ) {
System.out.print ( "(" + i + "," + data + ") " );
}
System.out.println ();
}
public static void main(String args[]) {
(new Queen()).compute( 8 );
}
}