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

书中的问题描述如下:象棋将帅问题:将帅不能在同一条直线上,各自在3*3的格子里面 ,请写出一个程序,要求用一个字节存储变量。书中给出了三种解法,我都贴在了下面。首先是代码思路:

*假设将为A,帅为B
*    遍历A的所有位置
*        遍历B的所有位置
*            判断A、B是否在同一直线上
*             若不在同一直线,则输出 

然后以下是三种方法的详细实现,我都是在DEV C++5.8.2版本编译器中编译通过的,代码中的算法策略注释片段是我的理解。

FirstSolution

#include <stdio.h>
/*
*算法策略: 
*声明一个字节的变量,将它的前四位设置为A的位置代号从0001到0101,即1到9 
*将它的后四位设置为B的位置代号也从0001到0101,即1到9 
*/ 
#define HALF_BITS_LENGTH 4
//这个值定为一个字节的一半
#define FALLMASK 255
//即FALLMASK为 1111 1111 
#define LMASK ( FALLMASK << HALF_BITS_LENGTH)
//即LMASK为 1111 0000
#define RMASK ( FALLMASK >> HALF_BITS_LENGTH)
//即RMASK为 0000 1111
#define LSET(b,n) (b = ((b & RMASK) | ((n) << HALF_BITS_LENGTH)))
//将b左边4位设置为n,首先将b左边4位置为0,再和n做“或”操作 
#define RSET(b,n) (b = ((b & LMASK) | (n)))
//同理,将b的右边4位设置为n,首先将b的右边四位置为0,再和n做“或操作 
#define LGET(b) ((LMASK & b) >> HALF_BITS_LENGTH)
//获取左边四位的值 
#define RGET(b) (RMASK & b) 
//获取右边四位的值
#define FRIDW 3 
int main()
{
    unsigned char b;
    for(LSET(b,1); LGET(b) <= FRIDW*FRIDW;LSET(b,(LGET(b)+1)))
    {
        for(RSET(b,1); RGET(b) <= FRIDW*FRIDW;RSET(b,(RGET(b)+1)))
        {
            if(LGET(b) % FRIDW != RGET(b) % FRIDW)
            printf("A = %d,B = %d\n",LGET(b),RGET(b));
        }
    }


} 

SecondSolution

#include <stdio.h>
#include <windows.h>
/*
*算法策略:
*声明一个BYTE型变量i,赋值为81 
*将i除以9的商记做A的位置,模3以后判断是否位置合法 
*将i模9的余数记做B的位置 ,模3以后判断是否位置合法 
*/ 
int main()
{
    BYTE i=81;
    while(i--)
    {
        if( i/9 % 3 == i%9%3 )
           continue;
        printf(" A = %d, B = %d \n",i/9 + 1,i % 9 + 1);
     } 
} 

ThirdSolution

#include <stdio.h>
/*
*算法策略:
*定义一个字节的结构体, 
*位域中的低四位设置为存储A的位置信息 
*位域中的高四位设置为存储B的位置信息
*比较模3以后的值是否相等 
*/ 
int main()
{
    /*
    *位域空间:位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
      struct 位域结构名
      { 位域列表 };
     其中位域列表的形式为:类型说明符 位域名:位域长度 
    */
    struct {
        unsigned char a:4;     //结构体变量a只使用其中低4位 
        unsigned char b:4;     //变量b使用高四位 
    } 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)
               printf("A = %d, B = %d\n",i.a,i.b);
 } 

因为是刚刚才开始研究算法,所以体会也不是很深,写这篇博客有两个目的:一是想记录一下自己的学习过程,另一个是想就书中提出的问题和大家讨论。问题是:有人说第三种算法策略是效率最高的,请读者自己证明。比较第二、三种算法,我的理解是每次循环,第二种算法每次产生的中间变量都要比第三种算法的多,那么内存的读写肯定开销就大,所以第三种算法效率就要高。希望大家看到的话,可以讨论讨论这个理解是否正确,欢迎回复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值