洛谷 P1219 八皇后(搜索 java实现)

在这里插入图片描述

     这题用到的思路就是深搜,但是深搜还是需要点优化,不然会超时。

 	 for(int i=1;i<=n;i++) {
    
    
            boolean flag=false;
            if(!book[i]) {
    
    
                for(int j=1;j<step;j++) 
                    if(step-j==Math.abs(i-nums[j])) {
    
    
                        flag=true;
                        break;
                    }
                }
                if(flag==true)
                    continue;
                nums[step]=i;
                book[i]=true;
                dfs(nums,step+1,n);
                book[i]=false;
            }
        }

    先说明一下变量都代表的什么意思,因为题目中行是默认升序的,我们只需要判断应该在哪一列就行,用i来遍历所有的列,j是来遍历所有的行,step表示是到达了第几行,nums数组的下标表示行数,下标对应的数组元素表示棋子放在该行的哪一列。

 			for(int j=1;j<step;j++) 
                    if(step-j==Math.abs(i-nums[j])) {
    
    
                        flag=true;
                        break;
                    }
                }

    上边的代码就是对角线的判断,对角线判断条件是 行-行==列-列,如果满足这个条件,表示在同一个对角线上,就不能要,从第一行开始判断,如果第step行-第j行 == 第i列-第j列的绝对值,因为step肯定比j大,所以不用带绝对值,而列数不一样,有可能第一行在最后一列,第二行在第三列这种情况,所以列数的差需要带个绝对值。

 				if(flag==true)
                    continue;
                nums[step]=i;
                book[i]=true;
                dfs(nums,step+1,n);
                book[i]=false;

    如果flag==true表示构成了对角线,所以就continue,到下一列,如果没有对角线,说明这个点是可以进入nums数组的,将其添加进去,并且标记这个点已经走过,接着遍历下一行,返回的时候要把标记去掉。

import java.util.*;

public class Main {
    
    
    static boolean[] book;//用来表示是否访问过
    static int cnt=0;
    public static void main(String[] args) {
    
    
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        book=new boolean[n+1];//下标从1开始,所以就是n+1
        int[] nums=new int[n+1];
        new Main().dfs(nums,1,n);
        System.out.println(cnt);
    }
    void dfs(int[] nums, int step, int n) {
    
    
        if(step==n+1) {
    
    //说明数字走完了,要退了
            cnt++;
            if(cnt<=3) {
    
    //因为只用输出前三个
                for(int i=1;i<=n;i++) {
    
    
                    System.out.print(nums[i]+" ");
                }
                System.out.println("");
            }
            return ;
        }
        
        for(int i=1;i<=n;i++) {
    
    
            boolean flag=false;
            if(!book[i]) {
    
    
                for(int j=1;j<step;j++) {
    
    
                    if(step-j==Math.abs(i-nums[j])) {
    
    
                        flag=true;
                        break;
                    }
                }
                if(flag==true)
                    continue;
                nums[step]=i;
                book[i]=true;
                dfs(nums,step+1,n);
                book[i]=false;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_51656756/article/details/120933347