标签:
学习《算法设计与分析基础》,习题2.4 第5题要求为汉诺塔游戏设计一个非递归的算法。
思,不得其解。看书后答案提示:
你如果做不到,也不要沮丧:这个问题的非递归算法虽然不复杂,但却不容易发现。作为一种安慰,可以在因特网上寻找答案。
好吧,话都说得这么直接了,遂百度之,得到一个感觉很好的答案,略做修改,摘录于下:
原文地址:http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html
#################################################################################
#################################################################################
void Hanoi(char src, char des, char via, int n) { Hanoi(src, via, des, n - 1); Move(src, des, n); //把第n个盘子直接从src移动到des Hanoi(via,des, src, n - 1); }
f(n + 1) = 2*f(n) + 1 -> [f(n + 1) + 1] = 2*[f(n) + 1] f(1) = 1,-> f(n) + 1 = (1 + 1)^n -> f(n) = 2^n - 1。 f(64)= 2^64-1=18446744073709551615
1 A->C 2 A->B 1 C->B 3 A->C 1 B->A 2 B->C 1 A->C
#include <iostream> using namespace std; void Hanoi(char src, char des, char via, int n) { if(n == 1) { cout << n <<" : "<< src <<" --> " <<des << endl; return; } Hanoi(src, via, des, n - 1); cout << n <<" : "<< src <<" --> " <<des << endl; Hanoi(via, des, src, n - 1); } int main() { int n; cin >> n; cout<<"recusive:"<< endl; Hanoi(‘A‘,‘C‘,‘B‘, n); cout << endl; cout<<"normal:"<<endl; char order[2][256]; char pos[64]; for(int i=0;i<64;i++) { pos[i]=‘A‘; //初始的时候,所有的圆盘位置都是 ‘A‘; } order[0][‘A‘] = ‘B‘; order[0][‘B‘] = ‘C‘; order[0][‘C‘] = ‘A‘; order[1][‘A‘] = ‘C‘; order[1][‘B‘] = ‘A‘; order[1][‘C‘] = ‘B‘; //0是顺序 1是逆序 int index[64]; //确定轨迹的顺序还是逆序 int i, j, m; for(i = n; i > 0; i -= 2) index[i] = 1; for(i = n - 1; i > 0; i -= 2) index[i] = 0; memset(pos, ‘A‘, sizeof(pos)); for(i = 1; i < (1 << n); i ++) { for(m = 1, j = i; j%2 == 0; j/=2, m ++); //计算出当前步骤序号的最低的 bit 为 1 的位置。 cout << m <<" : "<< pos[m] <<" --> " << order[index[m]][pos[m]] << endl; pos[m] = order[index[m]][pos[m]]; //更改当前位置 } return 0; }
感叹原作者提出的算法真是精妙。
另外补充:关于计算一个整数 bit 为 1 的最低位的问题,可以如下计算:
int lowestbit(int n) { int tmp=n-1; tmp=tmp^n; //假设n 的最低bit 为 1 的位为m,则此时 tmp 为低 m 位都为 1 、剩余高位都为 0 的数字。 tmp+=1; //此时 tmp= pow(2,m); return log2(tmp); }
标签:
原文地址:http://www.cnblogs.com/dongling/p/5720683.html