Chinaunix首页 | 论坛 | 博客
  • 博客访问: 432422
  • 博文数量: 103
  • 博客积分: 1455
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-15 22:17
文章分类

全部博文(103)

文章存档

2013年(4)

2012年(99)

我的朋友

分类: C/C++

2012-10-07 13:40:40

/*n皇后问题(该程序用回溯法解答)
 *
 *(C) LC
 */


#include<stdio.h>
#include<math.h>

#define MAX    20
static int    x[MAX];//利用一个一维数组表示棋盘,从1-8的数字分别表示皇后放在这一行的第几列
static int    sum;//全局变量用来求解一共有多少解法

/***************************************************

***判断k行放置在第i(in main)列的皇后是否可行******

***************************************************/
int Place(int k)//判断该位置可不可以放置皇后

{
    int     j;
    for(j = 1; j < k; j++)
        if((abs(k-j) == abs(x[j] - x[k])) || (x[j] == x[k]))  

/*由于算法是以行为数组分割的,所以不可能行重复,于是检测斜角是否重复和列是否重复,如果有斜角重复,则有两个元素的行列坐标的差值绝对值相等,如果有列重复,则有两个数组元素值(即列坐标)相等!***************************************************************************************/
            return    1;//如果重复则返回1 表示不能放置皇后
    return    0;//表示这样放置没有问题
}

void output(int x[], int n)
{
    int    i, j;
    int    a[n][n];
    for(i = 0; i < n; i++)
        for(j = 0; j < n; j++)
            a[i][j] = 0;
    for(i = 1; i <= n; i++)
    {
        if(x[i])
            a[i - 1][x[i] - 1] = 1;
    }
    for(i = 0; i < n; i++)
                {
            for(j = 0; j < n; j++)
                            printf("%d\t", a[i][j]);
            printf("\n");
        }

    printf("\n");
}

void Backtrack(int t, int n)
{
    int    i;
    if(t > n)//n为行列数,如果完全放下8行8列进入下一个
    {
        output(x, n);
        sum++;
    }
    else
        for(i = 1; i <= n; i++)
        {
            x[t] = i;//向第t行第i列放置一个皇后
     //     printf("good!%d\t%d\t%d\n", x[t], t, i);
/******************************************************

*************如果能放置,则计算t+1行的放置位置*********

******************************************************/
            if(!Place(t))
                Backtrack(t + 1, n);
        }
}



int main(void)
{
    int    n;
    printf("------------------------------\n");
    printf("please input n of the game!\n");
    scanf("%d", &n);
    Backtrack(1, n);
    printf("sum = %d\n", sum);
        
    return    0;    
}

 

回溯法的关键在于遍历到每一种情况,本例使用了函数的递归实现成功后的下一步;

好像没能找到用迭代法解的八皇后程序,想来还是需要8个循环嵌套实现,不知道又没有更简单的迭代算法

阅读(944) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~