<<编程之美>>1.2读后有感

  • 问题提出

    中国象棋的“将”,“帅”问题,他俩不能在一条直线上。求出他们的合法位置,并且只能用一个变量。

  • 分析

    一头雾水,不明所以。往下看了下,感觉像是程序员为难程序员的样子。只能用一个变量,并且只能用一个byte。一个byte有8位,前四位表示一个位置,后四位表示另一个位置。通过遍历位置找出互斥位置,并且去掉。大概思路是这样了。

  • 书中的解法

    

    第一种不是很懂,反正是操作一个byte的前四后四了。

    第二种,超级巧妙。运用了81%9和81/9作为数集,遍历了(1-9)*(1-9)这个域。我在mac下找不到byte这个变量,实在要用的话是使用unsign char来代替,它也是表示1byte的变量。更巧妙的是,如果两个数除3的余数是相等的,那肯定是互斥位置。

    int i = 81;
    while(i--){
        if(i / 9 % 3 == i % 9 % 3)
            continue;
        cout<<"A = "<<(i/9 + 1)<<" B = "<<(i%9 + 1)<<endl;
    }

    第三种,采用位域这个东西,把集合分成高位和低位存储,里面的变量更容易地去表示1-9,而且struct算一个变量?有点取巧。

    struct {
        unsigned char a:4;
        unsigned char b:4;
    } i;
    cout<<sizeof(i)<<endl;
    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)
                cout<<"A="<<(int)i.a<<" b="<<(int)i.b<<endl;

    我自己的解法,并不能与各位大牛相提并论啊,只能用很多的常量去控制这个计算了。主要思想还是高位低位分开,高位控制外层循环,低位控制里层。每次里层循环跳出的时候就会清空低位。(这一堆位运算也是够晕的)想了很久,试了很久,也算有所得吧。

    unsigned char c = 16;
    while((c&160) != 160){
        c  += 1;
        while((c&10) != 10){
            if((c>>4)%3 != (c&15)%3)
                cout<<"A = "<<(c>>4)<<" B = "<<(c&15)<<endl;
            c ++;
        }
        c  -= 10;
        c  += 16;
    }

原文地址:https://www.cnblogs.com/chentingk/p/6074781.html