高分问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高分问题相关的知识,希望对你有一定的参考价值。
八皇后问题
#include <stdlio.h>
using namespace std;
const int n=9;
int NUM;
int q[9];
bool C[9];
bool L[17];
bool R[17];
void Try(int n)
int j;
int k;
for(j=1;i<=8;j++)
if((C[j]==true)&&(L[i-j+N]==true)&&(R[i+j]==true))
q[i]=j;
C[j]=false;
L[i-j+n]=false;
R[i+j]=false;
if(i<8)
Try(i+1)
else
NUM++;
cout<<"方案"<<NUM<<":";
for(k=1;k<=8;k++)
cout<<q[k]<<"";
cout<<end;
C[J]=true;
L[i-j+n]=true;
R[i+j]=true;
int main()
int i,j;
NUM=0;
for(i=0;j<9;j++)
c[i]=true;
for(i=0;i<17'i++)
L[i]=R[i]=true;
Try(1);
return 0;
以上程序中,是一个八皇后问题递归解法,
能不能请大家详解一下其中的过程
我不能明白的是
else
NUM++;
cout<<"方案"<<NUM<<":";
for(k=1;k<=8;k++)
cout<<q[k]<<"";
cout<<end;
C[J]=true;
L[i-j+n]=true;
R[i+j]=true;
这个部分,,是在什么时候才会被执行?
是在递归达到边界条件(I=8)的时候才被执行一次啊, 还是
在递归回调的时候,每次都被执行
2:
)&&(L[i-j+N]==true)&&(R[i+j]==true))
这个一维数组怎么能代表对角线的数呢
?
3:
for(j=1;i<=8;j++)
这个语句是怎么被执行的?
因为我不明白是。当J=1时,他执行到TRY[I+1]时,就递归了,
递归之后,又遇到TRY[I+1],那J什么时候达到2?最底层的时候吗?
小弟是新手,对递归不 是很明了, 希望大家能够针对以上的例子详解一遍
首先要明确变量和函数的意义:
棋盘是8*8对吧?有左右对角线各15条。
放下一个queen之后,一行、一列、两个对角线就死了。
如果用true代表活,false代表死的话,
那么每一列的状态可以存储在布尔数组c[j]中,j在[1,8]。
每个对角线的状态放在布尔数组L和R中,程序里用的的下标是[2,16],如图:
数组L:_________数组R:
098765432________23456789
10\\\\\\\\______////////10
11\\\\\\\\______////////11
12\\\\\\\\______////////12
13\\\\\\\\______////////13
14\\\\\\\\______////////14
15\\\\\\\\______////////15
16\\\\\\\\______////////16
__\\\\\\\\______////////
(这是你第二个问题的答案,i是行,j是列,你看看是不是得到了对角线号?)
那为什么不找个数组表示"行"呢?因为程序是默认是按行迭代。第i个皇后必然在第i行上。所以不用了。
最后,把计算的结果放在数组q[]中,q[i]=j代表第i行第j列放一个queen。
try函数解释为:“试着放第n个皇后吧!”
那么程序就好读了:
主程序初始化各状态数组和变量,然后说:好了,试着放第一个皇后吧。
try(i)开始运作。(是i不是n)
(接下来是你的第三个问题)
for(j=1;j<=8;j++) (是j不是i)
这个循环说:请试着放在第j列上吧。
然后该判断了,第i行第j列能不能放皇后呢?这取决于
(C[j]==true)&&(L[i-j+N]==true)&&(R[i+j]==true)
如上所述,是棋盘上的第j列,第i-j+N条左对角线,第i+j条右对角线能放吗?
如果不能放了,就循环回来了,“试试下一列”。(你看回来了不是)
如果能放,那么
q[i]=j; //记录皇后所在的列
C[j]=false; //标记该列和两条对角线都不能再放皇后了
L[i-j+n]=false;
R[i+j]=false;
然后看看,现在放了几个皇后了?
if(i<8) ,那么还没放够八皇后,就在try(i+1),“试着放第i+1个皇后吧”
如果放够8个了,就到了你第一个问题的地方。将结果输出出来。
光得到一个方案还不够,还不想停下来,还想得到其它解法。
此时还原放这个皇后之前的状态
C[J]=true;
L[i-j+n]=true;
R[i+j]=true;
将行、对角线再设为可用。
然后去哪了呢?有回到for(j=1;i<=8;j++) 的地方试着放在下一列。
程序就解释完了。理解了吗?
理解这个程序的关键是递归的思想,如果你还不太懂,可以看看更简单的题目,比如汉诺塔和阶乘什么的,然后再看这个。
补充:
好的,感谢nomp45678朋友提出的意见。其实我是用记事本排好版的,但百度用的字体字号都不太好掌握(即使是在编辑框中看着还挺清晰的),显示出来的时候变了。你可以吧这部分复制到记事本里,如果没改过默认字体字号的话应该能看得比较清楚。
我再口头描述一下吧:
数组L中:
第8行第1列的位置所处的左对角线是16号左对角线,即L[16]
在其右上方的左对角线依次降序。
第1行第8列的位置所处的左对角线是2号左对角线,即L[2]
数组R中:
第1行第1列的位置所处的右对角线是第2号右对角线,即R[2]
在其右下方的右对角线依次升序。
第8行第8列的位置所处的右对角线是第16号右对角线,即R[16]
L[0],L[1],R[0],R[1]均没有使用。
这样说可以吗? 参考技术A 数组L:_________数组R:
098765432________23456789
10\\\\\\\\______////////10
11\\\\\\\\______////////11
12\\\\\\\\______////////12
13\\\\\\\\______////////13
14\\\\\\\\______////////14
15\\\\\\\\______////////15
16\\\\\\\\______////////16
__\\\\\\\\______////////
规划好点
以上是关于高分问题的主要内容,如果未能解决你的问题,请参考以下文章