最近看了一道微软的面试题题目是这样的:
下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且他们不能照面。在象棋残局中,许多高手能利用这一规则走出精妙的杀招。假设棋盘上只有将和帅,如下图所示
(为了描述方便,约定A表示将,B表示帅)
A和B二子被限制在己方3X3的个子里运动,例如,在如上的表格里,A被正方形{d10,f10,d8,f8 }包围,而B被正方形{d3,f3,d1,f1}包围
每一步,A,B分别可以横向或纵向移动一格,但不能沿对角线移动,另外,A不能面对B,也就是说,A和B不能处于同一纵向直线上
请些出一个程序,输出A,B所有合法位置,要求代码中只能使用一个变量。
在看参考答案之前我是这么思考的
将位置(1,4,7)(2,5,8)(3,6,9)分成三组其中第一组用三除余1,第二组余2,第三组整除(余0);
#include "stdio.h"
int main()
{
for(int i=1;i<10;i++)
{ if(i%3==1)
printf("%d,(%d,%d,%d,%d,%d,%d)\n",i,i%3+1,i%3+2,i%3+4,i%3+5,i%3+7,i%3+8);
if(i%3==2)
printf("%d,(%d,%d,%d,%d,%d,%d)\n",i,i%3-1,i%3+1,i%3+2,i%3+4,i%3+5,i%3+7);
if(i%3==0)
printf("%d,(%d,%d,%d,%d,%d,%d)\n",i,i%3+1,i%3+2,i%3+4,i%3+5,i%3+7,i%3+8);
}
return 0;
}
虽然满足了要求,但是总感觉是在按图索骥,依照答案找算法,技术含量不怎么高,且效率高低有待商榷。
《编程之美》作者给出几种答案如下
#include "stdio.h"
int main()
{
char i=81;
while(i--)
{
if(i/9%3==i%9%3)
continue;
printf("A= %d,B=%d\n",i/9+1,i%9+1);
}
return 0;
}
struct
{
unsigned char a:4;
unsigned char b:4;
}i;
main()
{
for(i.a=1;i.a<=9;i.a++)
for(i.b=1;i.b<=9;i.b++)
if(i.a%3!=i.b%3)
printf("A=%d,B=%d\n",i.a,i.b);
}