1.2 将帅问题

来源:互联网 发布:照片放到mac文件夹 编辑:程序博客网 时间:2024/05/16 00:37

1. 前言

本文的一些图片, 资料 截取自编程之美

2. 问题描述

这里写图片描述

3. 问题分析

我们先将这个问题换个方式表现出来
如下图, 我们假设将 & 帅的方位如下, 0-8 表示各个位置
从图中,我们可以看出, 只要((将的位置%3) == (帅的位置%3) ), 那么这将帅就照面了
我们需要求的是将帅不照面的情况, 所以我们需要的是((将的位置%3) != (帅的位置%3) )

因为要求我们只是用一个变量, 所以 必然涉及到位操作

这里写图片描述

4. 代码

代码如下 :
: 书中使用的是c, 使用的是宏定义, 这里改成java, 就是用了一些静态变量, 静态方法

/** * file name : Test07OfficerProblem.java * created at : 10:08:00 AM May 10, 2015 * created by 970655147 */package com.hx.test02;public class Test27OfficerProblem {        // 各个MASK常量, 以及各个边的长度, limit表示将 或者帅的最大位置的个数    private static int FULL_MASK;    private static int LEFT_MASK;    private static int RIGHT_MASK;    private static int SIDE_LENGTH;    private static int LIMIT;    static {         FULL_MASK = 255;         LEFT_MASK = (FULL_MASK  << 4) & 255;         RIGHT_MASK = (FULL_MASK >>> 4 ) & 255;         SIDE_LENGTH = 3;         LIMIT = SIDE_LENGTH * SIDE_LENGTH;    }    // 将帅问题  穷举    public static void main(String []args) {        // 这里用byte不好 因为涉及到byte -> int的转换 很容易混淆  所以这里使用int//      System.out.println(Integer.toBinaryString(RIGHT_MASK));//      byte b = 81;//      System.out.println(Integer.toBinaryString(b));//      System.out.println(Integer.toBinaryString(setLeft(b, 7)));//      System.out.println(Integer.toBinaryString(setRight(b, 3)));//      System.out.println(getLeft(b));        // 这里为了好看, 就多使用了变量cnt        int b = 0;        int cnt = 0;        for(b = setLeft(b, 0); getLeft(b) < LIMIT; b = setLeft(b, getLeft(b) + 1)) {            for(b = setRight(b, 0); getRight(b) < LIMIT; b = setRight(b, getRight(b) + 1)) {                if((getRight(b) % SIDE_LENGTH) != (getLeft(b) % SIDE_LENGTH) ) {                    System.out.println((++cnt) + " : " + getLeft(b) + " - " + getRight(b) );                }            }        }    }    // [设置/ 获取] [左边/ 右边] 的数据    public static int getLeft(int b) {        return (b & LEFT_MASK) >>> 4;    }    public static int getRight(int b) {        return b & RIGHT_MASK;    }    public static int setLeft(int b, int val) {        return (b & RIGHT_MASK) | (val << 4);    }    public static int setRight(int b, int val) {        return b & LEFT_MASK | (val);    }}

5. 运行结果

这里写图片描述

6. 总结

总的来说, 这个问题, 只要你有位操作的思路, 那么就不难
但是细节一定要注意, 记得在for循环的更新值的时候, 更新变量b

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

0 0
原创粉丝点击