-
首先,让我们先来温习递归:
调用前
一个函数的运行期间调用另一个函数时,在运行 被调用函数之前,系统需要完成3件事情:(3)将控制转移到被调函数的入口。调用中
而从 被调用函数返回调用函数之前,系统也应完成3件工作:(1)保存被调函数的计算结果;(2)释放被调函数的数据区;(3)依照被调函数保存的返回地址将控制转移到调用函数。当有多个函数构成 嵌套调用时,按照后调用先返回的原则。
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
-
输入:
-
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
-
输出:
-
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
-
2 1 92
-
15863724 84136275
样例输入:
-
样例输出:
#include <stdio.h>
int nCount=0;
int judge(int (*chess)[8],int row,int n)
{
int i,j,flag0=0,flag1=0,flag2=0,flag3=0,flag4=0;
//列
for(i=0;i<8;i++)
{
if (*(*(chess+i)+n)==1)
{
flag0=1;
break;
}
}
//左上
for(i=row,j=n;i>=0 && j>=0;j--,i--)
{
if (*(*(chess+i)+j)==1)
{
flag1=1;
break;
}
}
//左下
for(i=row,j=n;i<8 && j>=0 ;j--,i++)
{
if (*(*(chess+i)+j)==1)
{
flag2=1;
break;
}
}
//右上
for(i=row,j=n; i>=0 && j<8;j++,i--)
{
if (*(*(chess+i)+j)==1)
{
flag3=1;
break;
}
}
//右下
for(i=row,j=n; i<8 && j<8 ;j++,i++)
{
if (*(*(chess+i)+j)==1)
{
flag4=1;
break;
}
}
if (flag0 || flag1 || flag2 || flag3 || flag4)
{
return 0;
}
return 1;
}
void eightQueen(int (*chess)[8],int row,int n)
{
int chess2[8][8],i,j;
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
chess2[i][j]=chess[i][j];
}
}
if (row==8)
{
printf("第%d种解法是:\n",++nCount);
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
printf("%d ",*(*(chess2+i)+j));
}
printf("\n");
}
}else
{
for (i=0;i<n;i++)
{
if (judge(chess,row,i))//判断皇后是否可放非零可放
{
for (j=0;j<8;j++)
{
*(*(chess2+row)+j)=0;
}
*(*(chess2+row)+i)=1;
eightQueen(chess2,row+1,8);
}
}
}
}
int main()
{
int chess[8][8];
int i,j;
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
chess[i][j]=0;
}
}
eightQueen(chess,0,8);
return 0;
}
再来一个剪枝的回溯法吧:
#include <stdio.h>
#include <string.h>
int nCount;
bool isPlace(int row,int col,int (*queen)[8])
{
int i,j;
//判断行
for (i=0;i<8;i++)
{
if (1==queen[i][col])
{
return false;
}
}
//判断列
for (i=0;i<8;i++)
{
if (1==queen[row][i])
{
return false;
}
}
//判断左上
for (i=row-1,j=col-1;i>=0 && j>=0;i--,j--)
{
if (1==queen[i][j])
{
return false;
}
}
//判断左下
for (i=row+1,j=col-1;i<8 && j>=0;i++,j--)
{
if (1==queen[i][j])
{
return false;
}
}
//判断右上
for (i=row-1,j=col+1;i>=0 && j<8;i--,j++)
{
if (1==queen[i][j])
{
return false;
}
}
//判断右下
for (i=row+1,j=col+1;i<8 && j<8;i++,j++)
{
if (1==queen[i][j])
{
return false;
}
}
return true;
}
void Q(int k,int (*queen)[8])
{
int i,j;
if (k==8)
{
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
printf("%d ",queen[i][j]);
}
printf("\n");
}
printf("\n");
nCount++;
}else
{
for (i=0;i<8;i++)
{
if (isPlace(i,k,queen))
{
queen[i][k]=1;
Q(k+1,queen);
queen[i][k]=0;
}
}
}
}
int main()
{
int queen[8][8];
int i,j;
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
queen[i][j]=0;
}
}
Q(0,queen);
printf("the number of the answers are %d\n",nCount);
return 0;
}