基于C语言的n皇后问题
1.逻辑梳理
1.利用回溯法解决N皇后问题,逐行和逐列查找满足条件的位置 2.如果一整行都找不到满足条件的位置,那么回溯到上一行 3.解决N皇后问题,就是建立N*N的矩阵,但是N皇后超过20对电脑要求比较高 4.N皇后问题中,需要满足三个约束条件,不在同一行、同一列、同一斜线 5.当N=2,3时都受到约束条件的限制 6.在queens函数中调用dispasoulution(n);函数,实现输出解功能。place(k);函数实现确定皇后放置位置问题 7.在主函数中,用户从键盘输入n值,通过判断用户输入值的可行性,给出合理建议。
2.逻辑开发
2.1 dispasoulution函数
void dispasoulution( int n) //输出一个解
{
static int count = 0 ; //定义静态变量来统计解的个数
int i;
printf( "第%d个解:" ,++count) ; //每输出一次执行一次++
for( i= 1 ; i<= n; i++)
printf( "(%d,%d)" ,i,q[ i] ) ; //利用for循环依次输出解
printf( "\n " ) ;
}
2.2 place函数
int place( int k) //调用place函数判断能否放置该皇后
{
int i = 1 ;
while( i< k)
{
if (( q[i]== q[k]) || ( abs( q[i]- q[k]) == abs( i- k)) ) //判断是否满足约束关系,不能同列,不能同对角线
return 0 ;
i++;
}
return 1 ;
}
2.3 queens函数
void queens( int n)
{
int k = 1 ; //表示皇后个数或行数
q[ k] = 0 ; //表示当前列,从开头存放
while( 1 )
{
q[ k] = q[ k] +1; //测试下一列
while( q[ k] <= n&& ! place( k))
q[ k] = q[ k] +1;
if( q[ k] <= n) //找到第k个皇后的合适位置
{
if( k== n) //(皇后全部放置)
dispasoulution( n) ; //当满足k== n时,输出这个解
else
{
k++; //向下一行放置皇后
q[ k] = 0 ; //从第一列开始
}
}
else//如果没有找到合适的存放皇后的位置
{
if( k== 1 ) exit( 0 ) ; //如果回溯完成,算法结束
k--; //回溯到上一行
}
}
}
2.4 again函数
void again ( )
{
int n;
printf( "请重新输入一个合适的N值:\n " ) ;
scanf( "%d" ,& n) ;
if( n== 1 && n>= 4 || n<= 20 )
queens( n) ;
else
printf( "禁止再次输入\n " ) ;
}
2.5 主函数
int main ( )
{
int n;
printf( "n皇后问题(n<20)\n n=" ) ;
scanf( "%d" ,& n) ;
if( n> 1 && n< 4 || n> 20 )
{
printf( "n值不满足情况!\n " ) ;
again( ) ;
}
else
{
printf( "n皇后的问题求解如下:\n " ) ;
queens( n) ;
}
}
3.完整代码
#include< stdio. h>
#include< stdlib. h>
const int MAXN = 20 ;
int q[ MAXN ] ;
void dispasoulution ( int n)
{
static int count= 0 ;
int i;
printf ( "第%d个解:" , ++ count) ;
for ( i= 1 ; i<= n; i++ )
printf ( "(%d,%d)" , i, q[ i] ) ;
printf ( "\n" ) ;
}
int place ( int k)
{
int i= 1 ;
while ( i< k)
{
if ( ( q[ i] == q[ k] ) || ( abs ( q[ i] - q[ k] ) == abs ( i- k) ) )
return 0 ;
i++ ;
}
return 1 ;
}
void queens ( int n)
{
int k= 1 ;
q[ k] = 0 ;
while ( 1 )
{
q[ k] = q[ k] + 1 ;
while ( q[ k] <= n&& ! place ( k) )
q[ k] = q[ k] + 1 ;
if ( q[ k] <= n)
{
if ( k== n)
dispasoulution ( n) ;
else
{
k++ ;
q[ k] = 0 ;
}
}
else
{
if ( k== 1 ) exit ( 0 ) ;
k-- ;
}
}
}
void again ( )
{
int n;
printf ( "请重新输入一个合适的N值:\n" ) ;
scanf ( "%d" , & n) ;
if ( n== 1 && n>= 4 || n<= 20 )
queens ( n) ;
else
printf ( "禁止再次输入\n" ) ;
}
int main ( )
{
int n;
printf ( "n皇后问题(n<20)\nn=" ) ;
scanf ( "%d" , & n) ;
if ( n> 1 && n< 4 || n> 20 )
{
printf ( "n值不满足情况!\n" ) ;
again ( ) ;
}
else
{
printf ( "n皇后的问题求解如下:\n" ) ;
queens ( n) ;
}
}