一个4皇后问题,我的程序为什么不能通过!要考试了,急!!!!

PM0115 2004-01-05 03:20:14
我是用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
而实际上该程序没有任何输出!但我又找不出来原因,气死我了!
请大家帮我看看吧,
谢谢各位了!
...全文
77 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
PM0115 2004-01-08
  • 打赏
  • 举报
回复
谢谢楼上各位了,谢谢!
aaalife 2004-01-07
  • 打赏
  • 举报
回复
我给你改好了,测试ok~~~^_^ (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=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的棋盘
}
PM0115 2004-01-06
  • 打赏
  • 举报
回复
to 楼上的:我改为if(i==4)以后还是没有输出啊!
hyeena 2004-01-06
  • 打赏
  • 举报
回复
for(int j=1;j<=n;++j)//这里应该是(j=0;j<n;j++)
{
a[i][j]=1;
if (CanPlace(i,j,n))
Trial(i+1,n);
a[i][j]=0;
}

lemongxr 2004-01-06
  • 打赏
  • 举报
回复
我看了一下你的程序。发现在
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函数的第一个条件就返回○了。仔细看看吧。
另外,楼上几位的算法都比较精练,大可参考一下。
你的判断方法太繁了,效率不高,可以适当改进一下。
levinjoe 2004-01-06
  • 打赏
  • 举报
回复
改成:
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;
}
dengsf 2004-01-06
  • 打赏
  • 举报
回复
不知你考试了没有 :)

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

hyeena 2004-01-05
  • 打赏
  • 举报
回复
if(i>n)这里出错了,你的棋盘只有a[4][4],最多也就到3,到不了4的,所以是个无限递归啊!
aaalife 2004-01-05
  • 打赏
  • 举报
回复
N 皇后问题
(自己输入n值)

#include <iostream.h>
#include <math.h>


int stack[10];
int n,total;

void seek(int t) //seek the "t" row
{
int j,i,attack;

if(t==n) //if find one , output the path
{
total++;
for(j=0;j<n;j++)
cout<<stack[j]<<" ";
cout<<endl;
}


for(i=0;i<n;i++) // check whether (i+1) is legal or not ; row
{
attack=0;
stack[t]=i; //
for(j=0;j<t;j++) // row
{

if(abs(t-j)==abs(stack[t]-stack[j]) || (stack[t]==stack[j])) //if according this constraint, the one is illegal
{
attack=1;
j=t-1 ;
}
}
if(!attack) seek(t+1); //if not attack ; seek the next one

}
}

void main()
{
total=0;
cout<< "please input n : ";
cin>>n;
cout<<endl;
seek(0);
cout<<"the total number is : "<<total;
cout<<endl;
}
kwest 2004-01-05
  • 打赏
  • 举报
回复
/*************************************
*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;
}
kwest 2004-01-05
  • 打赏
  • 举报
回复
/*************************************
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;
}
LeeMaRS 2004-01-05
  • 打赏
  • 举报
回复
if(i>n) //如果放置了n个旗子

不对吧。i=n就可以了哇,表忘了你是在第i行是放置棋子,行的范围是0-3
PM0115 2004-01-05
  • 打赏
  • 举报
回复
那我上面的那个程序哪里错了呢?
敬请指教!!!
ZhangYv 2004-01-05
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/FAQ/FAQ_Index.asp?id=995
PM0115 2004-01-05
  • 打赏
  • 举报
回复
大家快帮帮我吧!要考试了!

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧