我是用C++,在VC6下调试的。
全部程序如下:
#include <iostream.h>
int a[4][4]; //定义一个4*4的棋盘
int CanPlace(int x,int y,int n) //该函数判断在(x,y)是否可以放置皇后,n表示棋盘是n*n的
{
int i,j;
if(a[x][y]==1) //判断该位置时候本来就有皇后
return 0;
for(j=y-1;j>=0;j--) //判断上方是否有皇后
if(a[x][j]==1)
return 0;
for(j=y+1;j<n;j++) //判断下方是否有皇后
if(a[x][j]==1)
return 0;
for(i=x-1;i>=0;i--) //判断左方是否有皇后
if(a[i][y]==1)
return 0;
for(i=x+1;i<n;i++) //判断右方是否有皇后
if(a[i][y]==1)
return 0;
i=x-1;
j=y-1;
while(i>=0&&j>=0) //判断左上方是否有皇后
if(a[i--][j--]==1)
return 0;
i=x+1;
j=y-1;
while(i<n&&j>=0) //判断右上方是否有皇后
if(a[i++][j--]==1)
return 0;
i=x-1;
j=y+1;
while(i>=0&&j<n) //判断左下方是否有皇后
if(a[i--][j++]==1)
return 0;
i=x+1;
j=y+1;
while(i<n&&j<n) //判断右下方是否有皇后
if(a[i++][j++]==1)
return 0;
return 1;
} //end Place
void Trial(int i,int n) // 递归函数,i表示该函数从i行起开始放置,n表示n*n的棋盘
{
/*进入本函数时,在n*n的棋盘前i-1行已经放置了互不攻击的i-1个棋子,现在从第i行起继续为后续旗子
选择合适的位置。当i>n时,求得一个合法的布局,然后输出该布局。
*/
if(i>n) //如果放置了n个旗子
{
for(int p=0;p<n;++p)
for(int q=0;q<n;++q)
if(a[p][q]==1) //当数组值为1时表示放置的是皇后
cout<<"p="<<p<<" "<<"q="<<q<<endl;
}
else
for(int j=1;j<=n;++j)
{
a[i][j]=1; //在第i行第j列放置一个棋子
if (CanPlace(i,j,n)) //如果当前布局合法
Trial(i+1,n); //到下一行继续放置
a[i][j]=0; //移走第i行第j列的棋子
}
} //end Trial
void main()
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][j]=0;
a[0][1]=1; //预先在第0行1列放置一个皇后,下面则从第1行开始放置
Trial(1,4); //其中1表示从第1行开始放置.其中,4表示是4*4的棋盘
}
我期望的输出结果是:
p=0 q=1
p=1 q=3
p=2 q=0
p=3 q=2
而实际上该程序没有任何输出!但我又找不出来原因,气死我了!
请大家帮我看看吧,
谢谢各位了!
http://expert.csdn.net/Expert/FAQ/FAQ_Index.asp?id=995
if(i>n) //如果放置了n个旗子
不对吧。i=n就可以了哇,表忘了你是在第i行是放置棋子,行的范围是0-3
/*************************************
N 皇后问题
*************************************/
#include <iostream.h>
#include <math.h>
#include <process.h>
#include <conio.h>
#define N 8 //define the N queens problem as 8 Queens problem
//===============Globe variable================//
int x[N+1];
int total=0;
////////////////////////////////////////////////
void output(void)
{
int i;
total++;
cout << "x[" << total << "]:";
for(i=1; i<=N; i++)
cout << x[i] << " ";
cout << endl;
}
/////////////////////////////////////////////////
int Place(int k)
{
int i;
for(i=1; i<k; i++)
{
if(x[i]==x[k] || abs(x[k]-x[i])==abs(k-i)) return 0;
}
return 1;
}
/////////////////////////////////////////////////
void dfs(int k)
{
int i;
if(k>N)
{
output(); //output the result
return;
}
for(i=1; i<=N; i++)
{
x[k]=i; //place the queen in the k row,i col
if(Place(k))
{
dfs(k+1); //search the k+1 line
}
}
return;
}
//==============Main() function=================//
int main(void)
{
dfs(1);
cout << "total=" << total << endl;
getch();
exit(0);
return 0;
}
/*************************************
*Problem : N Queens Problem
*Algorithm : Depth First Search
*Date : 2002-11-12
*Under the Turbo C 3.0 IDE
*************************************/
#include <iostream.h>
#include <math.h>
#include <process.h>
#include <conio.h>
#define N 8 //define the N queens problem as 8 Queens problem
//===============Globe variable================//
int x[N+1];
int total=0;
////////////////////////////////////////////////
void output(void)
{
int i;
total++;
cout << "x[" << total << "]:";
for(i=1; i<=N; i++)
cout << x[i] << " ";
cout << endl;
}
/////////////////////////////////////////////////
int Place(int k)
{
int i;
for(i=1; i<k; i++)
{
if(x[i]==x[k] || abs(x[k]-x[i])==abs(k-i)) return 0;
}
return 1;
}
/////////////////////////////////////////////////
void dfs(int k)
{
int i;
if(k>N)
{
output(); //output the result
return;
}
for(i=1; i<=N; i++)
{
x[k]=i; //place the queen in the k row,i col
if(Place(k))
{
dfs(k+1); //search the k+1 line
}
}
return;
}
//==============Main() function=================//
int main(void)
{
dfs(1);
cout << "total=" << total << endl;
getch();
exit(0);
return 0;
}
if(i>n)这里出错了,你的棋盘只有a[4][4],最多也就到3,到不了4的,所以是个无限递归啊!
不知你考试了没有 :)
void Trial(int i,int n)
{
if(i>n) //如果放置了n个旗子
{
for(int p=0;p<n;++p)
for(int q=0;q<n;++q)
if(a[p][q]==1)
cout<<"p="<<p<<" "<<"q="<<q<<endl;
}
else
for(int j=1;j<=n;++j)
=================================
还有这里有问题,改为 int j=0; j<n
{
a[i][j]=1;
if (CanPlace(i,j,n))
Trial(i+1,n);
a[i][j]=0;
}
} //end Trial
改成:
if (CanPlace(i,j,n))
{ a[i][j]=1; //如果当前布局合法
Trial(i+1,n); //到下一行继续放置
a[i][j]=0;
}//移走第i行第j列的棋子
你的程序逻辑错误,先把它=1,再判断是否为1 ,肯定返回0啊!
all:
#include <iostream.h>
int a[8][8]; //定义一个4*4的棋盘
int k=0;
int CanPlace(int x,int y,int n) //该函数判断在(x,y)是否可以放置皇后,n表示棋盘是n*n的
{
int i,j;
if(a[x][y]==1) //判断该位置时候本来就有皇后
return 0;
for(j=y-1;j>=0;j--) //判断上方是否有皇后
if(a[x][j]==1)
return 0;
for(j=y+1;j<n;j++) //判断下方是否有皇后
if(a[x][j]==1)
return 0;
for(i=x-1;i>=0;i--) //判断左方是否有皇后
if(a[i][y]==1)
return 0;
for(i=x+1;i<n;i++) //判断右方是否有皇后
if(a[i][y]==1)
return 0;
i=x-1;
j=y-1;
while(i>=0&&j>=0) //判断左上方是否有皇后
if(a[i--][j--]==1)
return 0;
i=x+1;
j=y-1;
while(i<n&&j>=0) //判断右上方是否有皇后
if(a[i++][j--]==1)
return 0;
i=x-1;
j=y+1;
while(i>=0&&j<n) //判断左下方是否有皇后
if(a[i--][j++]==1)
return 0;
i=x+1;
j=y+1;
while(i<n&&j<n) //判断右下方是否有皇后
if(a[i++][j++]==1)
return 0;
return 1;
} //end Place
void Trial(int i,int n) // 递归函数,i表示该函数从i行起开始放置,n表示n*n的棋盘
{
/*进入本函数时,在n*n的棋盘前i-1行已经放置了互不攻击的i-1个棋子,现在从第i行起继续为后续旗子
选择合适的位置。当i>n时,求得一个合法的布局,然后输出该布局。
*/
if(i>=n) //如果放置了n个旗子
{
for(int p=0;p<n;++p)
for(int q=0;q<n;++q)
if(a[p][q]==1) //当数组值为1时表示放置的是皇后
cout<<"p="<<p<<" "<<"q="<<q<<endl;
k++;
}
else
for(int j=0;j<n;++j)
{
//在第i行第j列放置一个棋子
if (CanPlace(i,j,n))
{ a[i][j]=1; //如果当前布局合法
Trial(i+1,n); //到下一行继续放置
a[i][j]=0;//移走第i行第j列的棋子
}
}
} //end Trial
void main()
{
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
a[i][j]=0;
//a[0][0]=1; //预先在第0行1列放置一个皇后,下面则从第1行开始放置
Trial(0,8); //其中1表示从第1行开始放置.其中,4表示是4*4的棋盘
cout<<k;
}
我看了一下你的程序。发现在
for(int j=1;j<=n;++j)
{
a[i][j]=1; //在第i行第j列放置一个棋子
????//注:
此处不应先给a[i][j]赋值。//
if (CanPlace(i,j,n)) //如果当前布局合法
Trial(i+1,n); //到下一行继续放置
a[i][j]=0; //移走第i行第j列的棋子
}
有点问题。a是全局变量,你先给a[i][j]赋了1,则进入CanPlace函数的第一个条件就返回○了。仔细看看吧。
另外,楼上几位的算法都比较精练,大可参考一下。
你的判断方法太繁了,效率不高,可以适当改进一下。
我给你改好了,测试ok~~~^_^
你的 判断 攻击的方法跟谁学的,真的挺麻烦的啊~~
#include <iostream.h>
int a[4][4]; //定义一个4*4的棋盘
int CanPlace(int x,int y,int n) //该函数判断在(x,y)是否可以放置皇后,n表示棋盘是n*n的
{
int i,j;
if(a[x][y]==1) //判断该位置时候本来就有皇后
return 0;
for(j=y-1;j>=0;j--) //判断上方是否有皇后
if(a[x][j]==1)
return 0;
for(j=y+1;j<n;j++) //判断下方是否有皇后
if(a[x][j]==1)
return 0;
for(i=x-1;i>=0;i--) //判断左方是否有皇后
if(a[i][y]==1)
return 0;
for(i=x+1;i<n;i++) //判断右方是否有皇后
if(a[i][y]==1)
return 0;
i=x-1;
j=y-1;
while(i>=0&&j>=0) //判断左上方是否有皇后
if(a[i--][j--]==1)
return 0;
i=x+1;
j=y-1;
while(i<n&&j>=0) //判断右上方是否有皇后
if(a[i++][j--]==1)
return 0;
i=x-1;
j=y+1;
while(i>=0&&j<n) //判断左下方是否有皇后
if(a[i--][j++]==1)
return 0;
i=x+1;
j=y+1;
while(i<n&&j<n) //判断右下方是否有皇后
if(a[i++][j++]==1)
return 0;
return 1;
} //end Place
void Trial(int i,int n) // 递归函数,i表示该函数从i行起开始放置,n表示n*n的棋盘
{
/*进入本函数时,在n*n的棋盘前i-1行已经放置了互不攻击的i-1个棋子,现在从第i行起继续为后续旗子
选择合适的位置。当i>n时,求得一个合法的布局,然后输出该布局。
*/
if(i>=n) //如果放置了n个旗子
{
for(int p=0;p<n;++p)
for(int q=0;q<n;++q)
if(a[p][q]==1) //当数组值为1时表示放置的是皇后
cout<<"p="<<p<<" "<<"q="<<q<<endl;
}
else
for(int j=0;j<n;++j)
{
//在第i行第j列放置一个棋子
if (CanPlace(i,j,n))
{ a[i][j]=1; //如果当前布局合法
Trial(i+1,n); //到下一行继续放置
a[i][j]=0;//移走第i行第j列的棋子
}
}
} //end Trial
void main()
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][j]=0; //a[0][0]=1; //预先在第0行1列放置一个皇后,下面则从第1行开始放置
a[0][1]=1; //预先在第0行1列放置一个皇后,下面则从第1行开始放置
Trial(1,4); //其中1表示从第1行开始放置.其中,4表示是4*4的棋盘
}