zoukankan      html  css  js  c++  java
  • 八皇后问题(回溯法)

    //在棋盘上放置八个皇后,使得他们互不攻击,每个皇后的攻击范围
    //是同行同列和同对角线要求找出所有的解
    void serarch(int cur)//cur是行
    {
    if(curn)tot++;//递归边界,只要走到这里所有的皇后必然不会冲突
    else
    {
    for(int i=0;i<n;i++)
    {
    int ok=1;
    c[cur]=i;//c[cur]代表的是列,尝试把第cur的皇后放在第i列
    for(int j=0;j<cur;j++)//检查是否和前面的皇后冲突
    if(c[cur]
    j||cur-c[cur]j-c[j]||cur+c[cur]j+c[j])
    {
    ok=0;
    break;
    }
    }
    if(ok)search(cur+1);//如果合法则继续递归
    }
    }
    //既然是逐行放置的就不会横向攻击,因此只需要检查纵向和斜向即可;
    //cur-c[cur]j-c[j]||cur+c[cur]j+c[j]是来检查
    //皇后(cur,c[cur])和(j,c[j])是否在同一条对角线上(画出棋盘图就可明白)

    /*
         程序效率可以进一步提高:利用二维数组vis[2][]直接判断当前的皇后所在列以及对角线已有
    其他的皇后,注意道到主对角线标识y-x可能为负数存取是要加上n;
    
    
    */
    
    void search(int cur
    {
       if(cur==n)tot++;
       else
        {
       	for(int i=0;i<n;i++)
       		if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])//利二维数组直接判断
       	 {
       		 c[cur]=i;//如果不用记录数组c则可以省略
       		vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
       		search(cur+1);
       		vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; //切记!!!!一定要该回来
       	 }
       }
    }
    /*
    上面的程序有个及其关键的地方:vis数组的使用,他表示已经放置的皇后占据了
    哪些lie 主对角线以及副对角线,一般的,如果在回溯法中修改了辅助的全局变量,则
    一定要及时的把它们恢复原状
    特别的 若函数有多个出口则在每个出口处修复被修改的值
    
    */
    梦里不知身是客,一晌贪欢。
  • 相关阅读:
    PAT甲级——A1006 Sign In and Sign Out
    PAT甲级——A1005 Spell It Right
    左神算法书籍《程序员代码面试指南》——1_05用一个栈实现另一个栈的排序
    左神算法书籍《程序员代码面试指南》——1_03如何使用递归函数和栈操作逆序一个栈
    PAT甲级——A1004 Counting Leaves
    PAT甲级——A1003Emergency
    Dijkstra算法
    PAT甲级——A1002 A+B for Polynomials
    PAT甲级——A1001A+BFormat
    Oil Deposits UVA
  • 原文地址:https://www.cnblogs.com/dccmmtop/p/5234983.html
Copyright © 2011-2022 走看看