蓝桥杯 试题 算法训练 王、后传说 dfs

算法训练 王、后传说 dfs

试题 算法训练 王、后传说

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  地球人都知道,在国际象棋中,后如同太阳,光芒四射,威风八面,它能控制横、坚、斜线位置。
  看过清宫戏的中国人都知道,后宫乃步步惊心的险恶之地。各皇后都有自己的势力范围,
但也总能找到相安无事的办法。
  所有中国人都知道,皇权神圣,伴君如伴虎,触龙颜者死…
  现在有一个nn的皇宫,国王占据他所在位置及周围的共9个格子,这些格子皇后不能使用
(如果国王在王宫的边上,占用的格子可能不到9个)。当然,皇后也不会攻击国王。
  现在知道了国王的位置(x,y)(国王位于第x行第y列,x,y的起始行和列为1),请问,
有多少种方案放置n个皇后,使她们不能互相攻击。
输入格式
  一行,三个整数,皇宫的规模及表示国王的位置
输出格式
  一个整数,表示放置n个皇后的方案数
样例输入
8 2 2
样例输出
10
数据规模和约定
  n<=12
分析:
1,有n个皇后所以在n
n的空间内每一行都要有一个皇后(如果有两个皇后在同一行内显然不符合条件);
2,试探的性的依次往每一层加入一个皇后看是否满足条件
所以现在就有两个步骤一个是试探性的填入皇后一个是检验是否满足题目给出的条件

import java.util.*;
public class Main{
    public static int x;//保存王的行位置
    public static int y;//保存王的列位置
    public static int sum=0;//统计有多少种方式
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		    x=sc.nextInt();
		    y=sc.nextInt();
		//用来记录每一位皇后的位置的,下标是行数,数值是列数  
		int arr[] = new int[n+1];
		dfs(arr,1);//从第1行开始
		System.out.println(sum);
       
	}
	private static void dfs(int[] arr, int cur) {//cur是表示层数
		if(cur==arr.length) {
			sum++;
			return;
		}
	    for (int i = 1; i < arr.length; i++) {//第几列
			if(check(arr,cur,i)) {//cur当前的层数,i第几个
				arr[cur]=i;
				dfs(arr, cur+1);
			}
		}
	    arr[cur]=0;//回溯
		
	}
	private static boolean check(int[] arr, int cur, int k) {//cur 是层数,k是列数
		//判断有没有在王的9个格子中
		for (int i =x-1; i <=x+1; i++) {
			for (int j =y-1; j <=y+1; j++) {
				if(i==cur&&k==j)return false;
			}
		}
		//判断有没有在其他皇后的同列和同行是不是在一个对角线上
		for (int i = 1; i <cur; i++) {//arr[i]表示的是第几列
			if(arr[i]!=0) {//arr[i]!=0 表示这个点有皇后
				if(i==cur)return false;//同行
				if(arr[i]==k)return false;//同列
				
				if((arr[i]-i)==(k-cur))return false;//反对角线
				if((arr[i]+i)==(k+cur))return false;//正对角线
				
			}
		}
		
		return true;
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值