编程之美-中国象棋将帅问题

来源:互联网 发布:如何保持身材 知乎 编辑:程序博客网 时间:2024/04/30 23:41

中国象棋将帅问题

问题描述

下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且它们不能照面。在象棋残局中,许多高手能利用这一规则走出精妙的杀招。假设棋盘上只有“将”和“帅”二子(为了下面叙述方便,我们约定用A表示“将”,B表示“帅”): 


A、B二子被限制在己方3×3的格子里运动。例如,在如上的表格里,A被正方形{d10, f10, d8, f8}包围,而B被正方形{d3, f3, d1, f1}包围。每一步,A、B分别可以横向或纵向移动一格,但不能沿对角线移动。另外,A不能面对B,也就是说,A和B不能处于同一纵向直线上(比如A在d10的位置,那么B就不能在d1、d2以及d3)。
请写出一个程序,输出A、B所有合法位置。要求在代码中只能使用一个变量。

思路

刚开始我的思路是: 先不考虑一个变量的限制,写出解决方案后在去优化.以a1为原点,a-t为X轴,1-10为Y轴建立坐标系.A,B不能照面也就是A,B的横坐标不能相同.
方法一:
遍历A所有情况,直接输出B符合条件的情况.(直接输出是说,code中没有判断A,B横坐标相等与否的情况,而是直接输出正确的坐标.)
整个棋盘以二维数组存储arr[SIZE][SIZE].两个for循环遍历出A的所有情况,当A在第d列的时候,输出B在e,f的点,当A在第e列的时候,输出B在d,f的点,当A在第f列的时候,输出B在d,e的点.
问题来了,这样处理可以输出满足条件的情况,可是不能满足一个变量的情况.要是A,B在一个10000x10000的格子里面运动,那么直接输出的逻辑就有点复杂了.整理下问题:

  • 直接输出
  • 一个变量          
  • 思考--直接输出
    为什么随着格子数的递增,直接输出方法的复杂度也在递增呢?
    回顾下这个方法之前,想起来了OJ的后台系统,用户在本地编写好程序后,将代码提交到服务器,服务器生成该程序,然后运行程序,读取对应的input文件,将输出将文件与对应的output比较,如相等则AC.整个流程是:
    输入-->机器处理-->输出
    方法一的流程是:
    输入-->自己处理-->输出
    一对比就发现方法一的流程有问题: 把核心的计算部分自己处理了(横坐标相等与否),程序只是做了一点输出的工作,因此导致问题1的出现.知道了原因修改起来就方便多了.将判断部分也交给程序去处理.
    思考--一个变量
    解决了逻辑的问题,还有变量存储的问题,就是怎么把所有数据存储在一个变量里面.之前用到过二维数组,仔细想想二维数组可以优化成一维数组(想起了三体的宏原子按层展开).个数为2×3×3,因为这个一维数组是递增的(有规律的),因此一维数组可以继续优化,用一个变量辅助循环来存储.这样的话18个数,一个byte就够了,前4bit存储A,后4bit存储B.整个流程是:
    二维数组-->一维数组-->一个变量
    方法二:

    根据方法一的改进不难得出新的方法:遍历A的所有情况,遍历B的所有情况,判断A,B的横坐标是否相等,输出结果.

    小结

  • 数据存储:二维数组-->一维数组-->一个变量(借助循环)
  • 输入-->机器处理-->输出(不本末倒置替机器做事情)

  • 原创粉丝点击