中国象棋将帅问题

来源:互联网 发布:淘宝闲鱼手机版网页 编辑:程序博客网 时间:2024/03/29 01:40

来源:编程之美-微软技术面试心得

在中国象棋中,将帅只能在两个九宫格里,且将帅不能见面,即不能同时出现在一列里,


问题:请输出将帅所有可能的位置,只能用一个字节实现

分析:这个问题的难点在于变量只能使用一个字节,

很显然,大致的解法就是两个for循环,然后判断将帅是否在同一列,不在则输出。

设:A=‘将’,B=‘帅’,九宫格用1,2,3,……,9来表示。

解法一:

A或B可能的位置是九个,则可以使用4BIT来记录其位置,如此正好满足题目要求

编程中要使用到的操作就是位操作

1.设置低四位为n,保留高四位

先清除低四位:X&11110000

设置低四位:X|0000xxxx(n)

2.设置高四位,保留低四位

先清除高四位:X&00001111

设置高四位:X|xxxx1111(n)

3.分别输出高四位,低四位

输出高四位:X>>4

输出低四位:X&00001111

#include<stdio.h>

#define HALF_BITS_LENGHT 4

//记忆存储单元的一半

#define FULLMASK 255

//11111111

#define LMASK (FULL_MASK << HALF_BITS_LENGTH)

//11110000

$define RMASK (FULL_MASK >> HALF_BITS_LENGTH)

//00001111

#define RSET(b,n) (b = ((LMASK&b)|n))

//设置低四位为n,保留高四位

#define LSET(b,n) (b = ((RMASK&b)|(n<<HALF_BITS_LENGTH)))

//设置高四位,保留低四位

#define RGET(b) (RMASK&b)

//获取低四位

#define  LGET(b) (LMASK&b)

//获取高四位

#define GRIDW 3

//定义棋盘

int main(){

unsigned char b;//定义变量

for(LSET(n,1);LGET(b)<=GRIDW*GRIDW;LSET(b,(LGET(b)+1))){

for(RSET(n,1);RGET(b)<=GRIDW*GRIDW;RSET(b,(RGET(b)+1))){

if(RGET(b)%GRIDW != LGET(b)%GRIDW){

printf("A=%d,B=%d\n",LGET(b),RGET(b));

}

}

}

return 0;

}

解法二:

很显然,A,B可能的组合是81种,(0,0)~(9,9)

BYTE i=81;

while(i--){

if(i / 9 % 3 == i % 9 % 3){

continue;

}

rintf("A=%d,B=%d\n",i/9+1,i%9+1);

}

解法三:

考虑到只能使用一个字节的存储空间

那么,可以使用位域的概念

位域的概念,参考http://blog.csdn.net/havedream_one/article/details/41541221

struct{

unsigned char a:4;

unsigned char b:4;

}i;

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){

rintf("A=%d,B=%d\n",i.a,i.b);

}

}

}


0 0
原创粉丝点击