n皇后

运行时间:2115ms

占用内存:13580k

这个时间有点长,看别人都是<1ms的,不过总算是AC了

/** 
 * n皇后问题 
 * 每一行每一列,同一斜线上不能出现2个皇后 
 * 解题思路: 
 * 回溯法 
 * 每列只能放1个皇后,每列就有n种方法,n列一共就是n^n种方法,这么多方法种可定包含了所有n皇后的解。当第一列放一个皇后的时候,就会产生一颗解空间树,由此树的第二层会有n个节点,第三层会有n*n个节点... 
 * 树的第n层会有n^n-1个节点,,这样就构成了一颗解空间树,这样的树随着第一列n种放皇后的情况,会有n棵树,那么一共就有n^n-1*n = n^n种解,那么如何在这些解中获取正确的答案? 
 * 随着一棵树开始,往下深度优先进行搜索, 
 * 1)当发现当前皇后的位置合法,继续往下搜索,知道叶子节点后,符合皇后解答,计数,然后回溯上一层,继续下一条分支 
 * 2)当发现当前位置不合法,那么就没有必要从当前节点往下衍生了,继续下一条分支 
 */  
package dp;  
import java.util.Date;  
import java.util.Scanner;  
public class Main {  
    static int count = 0;  
    public static void main(String[] args){  
        Scanner in = new Scanner(System.in);  
        int n = in.nextInt();  
        nQueens(n);
        System.out.println(count);
    }  
    public static int nQueens(int n) {  
        if(n < 1) return 0;  
        // write code here  
        int[][] q = new int[n][n];  
        queens(0, q);//从第0列开始
        return count;
    }  
    public static void queens(int i, int[][] q){  
        if(i >= q.length){ //当前列递归出去了,结束
            //递归结束,得到一组解  
            count++;  
            return ;
        }  
        //根据当前列,应该有n中放法,从第一行开始到第n行进行讨论       
            for(int k = 0; k < q.length; k++){
                if(isCorrect(k, i, q)){//当前k行,i列皇后合法,递归去处理下一列  
                    q[k][i] = 1;//放上去  
                    queens(i+1,q);//递归出列下一列,将所有合法的解记录夏下来(深度优先搜索)  
                    q[k][i] = 0;//晴空当前位置,继续讨论下一颗解空间树,即当前列的下一行  
                }else{  
                    //当前列当前行不合法,那么就去当前列的下一行  
                }  
            }          
    }  
    public static boolean isCorrect(int j, int k, int[][] q){  
        //判断当前位置的皇后是否合法  
        //该行  
        for(int i = 0; i < q.length; i++){  
            if(q[j][i] == 1 && i != k) return false;  
        }  
        //该列  
        for(int i = 0; i < q.length; i++){  
            if(q[i][k] == 1 && i != j) return false;  
        }  
        //左上  
        for(int i = j-1, w = k-1; i>=0 && w>=0; i--,w--){  
            if(q[i][w] == 1) return false;  
        }  
        //右下  
        for(int i = j+1, w = k+1; i<q.length && w < q.length; i++, w++){  
            if(q[i][w] == 1) return false;  
        }  
        //右上  
        for(int i = j-1, w = k+1; i>=0 && w<q.length; i--,w++){  
            if(q[i][w] == 1) return false;  
        }  
        //左下  
        for(int i = j+1, w = k-1; i < q.length && w >= 0; i++,w--)  
            if(q[i][w] == 1) return false;  
        return true;  
          
    }  
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值