买了本编程之美 打算以后看看 也在这里记录一下有关算法方面的东西
有关象棋将帅的位置问题
假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面。问在这样条件下,所有可能将帅位置。要求在代码中只能使用一个字节存储变量。
将帅的田字格自然都可以分为就这样 问题就变成 两个一到九的循环 他们对于3的余数不能一样 一样的话将帅就碰面了
这样的问题 我也花三分钟写完 但问题来了?
什么叫做一个字节储存变量
一个字节 8位,普通的int 是32位 8位只能表示到255 但问题是我们需要两个变量啊,一个字节 是只能用一个变量嘛,还是一个字节可以储存多个变量?
于是我辈俗人根本就没用过的byte登场了, (byte具体是什么不一定 但肯定是一个字节)
我们知道无符号数unsigned char 11111111 可以表示 到255 那我们就把它一分为二嘛,左边4位当将 后边4位当帅 然后就可以了 但是代码量真是多到看不懂
另外一种 就是位域了
1 #include<stdio.h>
2 struct {
3 unsigned char a:4; //半个字节放将
4 unsigned char b:4; //半个字节放帅
5 } i; //一个字节储存变量达成
6 int main()
7 {
8 for(i.a = 1; i.a <= 9;i.a++)
9 for(i.b = 1;i.b <=9;i.b++)
10 if(i.a % 3 != i.b % 3)
11 printf("A=%d,B=%d\n",i.a,i.b);
12 return 0;
13 }
一个变量
但其实我们只是想办法把两个变量放在一个字节中 ,一个结构体中 能不能就来一个变量呢?
void Chess2 (void) {
unsigned 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);
}
}
其实这个解法也是一个困扰了我很久的问题 关于 取模
经常有那种围成圈的例子 必须取模绕回去
想看懂必须要明白 i/9 和i%9
一个整数可以有两部分var=(var/9)*9+var%9
整个var有很多个9 在这很多个9里面 又有不同
0 9
8 8 //后面是外循环 里面是内循环 一目了然
7 8 //当然最后得+1
6 8
5 8
4 8
3 8
2 8
1 8
0 8
8 7
7 7
6 7
5 7
4 7
3 7
2 7
1 7
0 7