微软面试心得-将棋算法

阅读编程之美:微软技术面试心得总结

~中国象棋将帅问题

‘将’和‘帅’都各自在自己的‘大本营’移动,在程序中输出所有两个棋子不在一条线上落子方法,只能使用一个变量。

~算法分析

抛开只使用一个变量的要求,这其实是一个很简单的问题,用0到8九个数字代表落子的位置,遍历每一个数字,对3进行求余,如果余数不相等,就代表没在一条直线上。
如果没有只使用一个变量的要求的确很简单,代码如下:

int jiangTemp;
int shuaiTemp;

for(jiangTemp = 0; jiangTemp < 9; jiangTemp++)
{
    for(shuaiTemp = 0; shuaiTemp < 9; shuaiTemp++)
    {
        if(shuaiTemp%3 != jiangTemp%3)
        {
            cout<<"没有在一条直线上"<<endl;
        }
    }
}

很简单的程序,但是如果只是用一个变量的话,就得用一个变量代表两个数字,数字范围不需要很大,能容纳下9个数字就行,bool值只能代表两个数字,因此不可用,int值范围又太大,因此我们折中选择byte,byte是一个8位的类型,可以表示256个数字,我们用前4位代表将棋,用后四位代表帅棋。

第一步:对右边四位赋值

这里我们只做一次循环的分析,假设byte b当前的值为:

10100101

我们先清除掉右边4位的值,获得左边四位的值:

11110000&10100101

上边运算得出结果:

10100000

然后让结果和n(需要给右边四位复制的数字)^运算:

10100000^00000011

得出结果:

10100011

这样就完成了对右边四位的赋值

第二步:对左边四位赋值

我们先清除掉左边4位的值,获得左边四位的值:

00001111&10100011

得出结果:

00000011

将需要赋值的数字n向左移动四位:

n<<4 = 00110000

byte b和n的值进行^运算:

00110000^00000011

得出结果:

00110011

第三步:左右两个值进行运算

清除左边4位:

00110011&00001111

得出结果:

00000011

清除右边4位:

00110011&11110000

得出结果:

00110000

将结果向又有移动4位:

00110000>>4 = 00000011

得到的两个结果分别%3结果不相等则输出没在一条直线上。

代码如下:

#include <stdio.h>
#define HALF_BITS_LEN 4
#define FULL_MASK 255
#define LMASK (FULL_MASK << HALF_BITS_LEN)
#define RMASK (FULL_MASK >> HALF_BITS_LEN)
#define RSET(b, n) (b = (LMASK & b) ^ n)
#define LSET(b, n) (b = (RMASK & b) ^ (n << HALF_BITS_LEN))
#define RGET(b) (RMASK & b)
#define LGET(B) ((LMASK & B) >> HALF_BITS_LEN)
#define GRIDW 3

int main()
{
    unsigned char b;
    for (LSET(b, 1); LGET(b) < GRIDW*GRIDW; LSET(b, LGET(b) + 1))
    {
        for (RSET(b, 1); RGET(b) < GRIDW*GRIDW; RSET(b, RGET(b) + 1))
        {
            if (LGET(b) % GRIDW != RGET(b) % GRIDW)
            {
                printf("A = %d, B = %d\n", LGET(b), RGET(b));
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值