您的位置:首页 > 编程语言

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

2012-09-26 18:13 267 查看

中国象棋将帅问题

问题描述

下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且它们不能照面。在象棋残局中,许多高手能利用这一规则走出精妙的杀招。假设棋盘上只有“将”和“帅”二子(为了下面叙述方便,我们约定用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的横坐标是否相等,输出结果.

小结

数据存储:二维数组-->一维数组-->一个变量(借助循环)
输入-->机器处理-->输出(不本末倒置替机器做事情)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: