八皇后问题
八皇后问题是一个以国际象棋为背景的问题:如何能够在8*8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他皇后?为了到达此目的,任两个皇后都不能处于同一条横行,纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题。
输入:一个数字n,表示在n*n的表格上,合理的摆放n个皇后。
输出:输出n个皇后所能摆放的全部可能性,0-该位置不摆放皇后,1-在该位置摆放皇后。
样例输入:
1
No answer!!!
2
No answer!!!
4
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
…….
问题分析:
该问题是一个约束满足问题。
CSP(constraint satisfy problem 约束满足问题):有一个变量集合和一个约束集合组成。问题的一个由对一些或全部变量的一个赋值定义的完全赋值:每个变量都参与的赋值。问题的解是满足所有约束的完全赋值,或更进一步,使目标函数最大化。
对于该问题而言,如果是输入的是8,那么就是对8*8的矩阵进行赋值,使其满足该问题的描述。
用Xi表示第i个皇后所在列的位置(i表示所在行,Xi表示所在的列)。
那么X1~X8的不同的赋值就是该CSP问题的变量集合,但是只有这些变量集合的赋值满足约束条件的时候才能得到正确解。
该问题的约束条件为:1.任何两个皇后所在的行不相等(Xi和Xj中i!=j)。2.任何两个皇后所在的列不相等(Xi!=Xj)。3.任何两个皇后都不在一个斜线上(对于Xi和Xj而言,|i-j|!=|Xi-Xj|)。
只要在上述的变量集合中找出满足约束条件的变量就能正确解答该题目。
#include<stdio.h>
#define max 100
int a[max][max];
int n;
int num;
void init_array()
{
int i,j;
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
a[i][j] = 0;
}
void print_array()
{
int i,j;
printf("***********************\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("***********************\n\n");
}
int absolute_number(int x,int y)
{
int number ;
number = x-y;
if(number<0)
return -number;
return number;
}
void resolute_problem(int level)
{
if(level==n+1)
{
num = 1;
print_array();
}
else
{
int i,j,k;
int flag;
for(i=1;i<=n;i++)
{
flag = 1;
/////////判断列
for(j=1;j<level;j++)
{
if(a[j][i]==1)
{
flag = 0;
break;
}
}
/////////判断对角线
for(j=1;j<level;j++)
{
for(k=1;k<=n;k++)
{
if(a[j][k]==1)
break;
}
if(absolute_number(level,j)==absolute_number(k,i))
{
flag = 0;
break;
}
}
/////////判断是否满足条件
if(flag ==1)
{
a[level][i] = 1;
resolute_problem(level+1);
a[level][i] = 0;
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init_array();
num = 0;
resolute_problem(1);
if(num==0)
{
printf("No answer!!!\n");
}
}
return 0;
}