马的管辖

马的管辖

在中国象棋中,马是走日字的。一个马的管辖范围指的是当前位置以及一步之内能走到的位置,下图的绿色旗子表示马能走到的位置。

如果一匹马的某个方向被蹩马脚,它就不能往这个方向跳了,如下图所示,海星的位置存在旗子,马就不能往上跳到那两个位置了:

那么问题来了,在一个 n×m 的棋盘内,如何用最少的马管辖住所有 n×m个格子。比如 n=m=3 时,最少要用 5 只马才能管辖所有棋盘,一种可能的方案如下:

思路

状态压缩,把二维的棋盘压缩到一维的数组中(n行m列存入一维大小为n*m的数组中),然后二进制求出所有的情况。

然后对于每种情况转化为二维坐标,判断有马的地方要跳的位置(以当前点为源点,可以循环出所有可能的方向)。

对于可以跘马脚的位置,由坐标的关系可以得出然后再判断可不可以跳。

用sum变量记录总的覆盖数(刚开始为马的数量),判断是否覆盖完来决定是否可取。

最后注意要求的是方案数,然后对于每个满足条件的最少马数来求答案。

import java.util.Scanner;
 
public class Main {
 
	static int m,n;
	public static void main(String[] args){
		Scanner cin=new Scanner(System.in);

		n = 5;
		m = 5;
		
		int ans = n*m; //最少马数
		int cnt = 0; //对应方案数
		for(int i=0; i<(1<<(n*m)); i++) { //枚举每个格子的01状态
			int[][] map = new int[n+5][m+5];
			int sum = 0;
			for(int j=0; j<(n*m); j++) {
				int t = ((1<<j)&i) > 0 ? 1 : 0;
				
				sum += t; 
				int row = (j+m)/m; //转化为二维坐标
				int col = (j+1)%m;
				if(col == 0) col = m;
				map[row][col] = t;
			}
			
			if(getAns(map, sum)) {
				if(ans == sum){
					cnt ++;
				}else if(ans > sum){
					cnt = 1;
					ans = sum;
				}
			}
		}
		System.out.println(cnt);
	}

	static int[][] dir = {{-2,-1}, {-2,1}, {-1,-2}, {-1, 2},
			{1, -2}, {1, 2}, {2, -1}, {2, 1}};
	private static boolean getAns(int[][] map,int sum) {
		//1 马
		//2 覆盖
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++) {
				if(map[i][j] == 1) {
					for(int d=0; d<8; d++) {
						int x = i + dir[d][0]; //能到的八个方向
						int y = j + dir[d][1];
						if(x < 1 || x > n || y < 1 || y > m) continue;
						if(map[x][y] == 0) { //不考虑别马脚的情况可以到的情况
							int xi = dir[d][0] / 2 + i; //别马脚所处的位置
							int yj = dir[d][1] / 2 + j;
							if(map[xi][yj] == 1) continue; //该位置有马
							map[x][y] = 2;
							sum ++;
						}
					}
				}
			}
		}
		return sum == n*m ? true : false;
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值