八皇后问题 java

╄→гoц情女王★ 提交于 2020-03-01 21:17:06

在棋盘上放置8个皇后,使他们互不攻击,此时每个皇后的
攻击范围为

  • 同行
  • 同列
  • 同对角线
  • 要求找出所有解

恰好每行每列放置一个皇后
如果用C[x]表示第x行皇后的列号,就成为了一个全排列问题

static int ans;
    static int n;
    static int[] C;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        C=new int[n];
        f(0);
        System.out.println(ans);
    }
    static void f(int cur){
        if(cur==n)ans++;

        else for(int i=0;i<n;i++){
            int ok=1;
            C[cur]=i;
            for(int j=0;j<cur;j++){ //检查是否和前面的皇后冲突
                //判断是否跟前面的皇后在同一列或者对角线
                // 因为数组下标就是行号,所以不会在同一行
                if(C[cur]==C[j]||cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j]){
                    ok=0;
                    break;
                }
            }
            if(ok==1){
                f(cur+1);
            }

        }
    }
cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j]  这个是判断两个皇后是不是在对角线上,如果在对角线上,说明这个方法不能取 

下面代码是基于上面的方法提高了效率
跟上面的代码比较,下面用二维数组来存储是否跟之前皇后冲突
就不用每次递归的时候再用for循环进行判断了
要注意的是递归的最后要进行回溯

static int ans;
    static int n;
    static int[] C;
    static boolean[][] vis;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        C=new int[n];
        vis=new boolean[3][2*n];
        for(int i=0;i<3;i++){
            for(int j=0;j<2*n;j++){
                vis[i][j]=false;
            }
        }
        f(0);
        System.out.println(ans);
    }

    /**
     * 可以声明一个二维数组来判断当前皇后和之前皇后位置是否冲突
     *
     * @param cur
     */
    static void f(int cur){
        if(cur==n)ans++;

        else for(int i=0;i<n;i++){
            if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){ //用二维数组来存放冲突位置
                //cur-i+n   后面加上n的原因是因为cur-i可能是负数
                C[cur]=i;
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=true;
                f(cur+1);
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=false; //回溯
            }
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!