汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。

汉诺塔VIII,在经典汉若塔问题上。问n个盘子的情况下,移动m次以后,是什么状态。

(与第七代互为逆命题)

我的思路:本质还是dfs,可是用m的值来指引方向,每搜一层确定第i个盘子在哪个塔,o(n)的算法,看图说明:

汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。_第1张图片

#include
#include
using namespace std;
char get[65];   //记录I号盘子在哪个塔
long long f[65]; //2^i次的值
void got()   //预处理的f[i]; 注意点:用1<

{ f[1]=2; for(int i=2;i<65;i++) f[i]=f[i-1]*2; } void dfs(char fl,char fr,char now,int lev,long long x) //同汉若塔第七代理。LVE是层数。x是眼下的值 { get[lev]=now; if(lev==1)return; //出口 char temp; if(fl=='A'&&fr=='B'||fl=='B'&&fr=='A')temp='C'; else if(fl=='A'&&fr=='C'||fl=='C'&&fr=='A')temp='B'; else temp='A'; lev--; long long tx=(f[lev]-1)/2; if(x<=tx) //小于它的 { if(now==fl) //左边的下来 dfs(fl,temp,fl,lev,x); else dfs(temp,fr,temp,lev,x); } else { if(now==fl) dfs(fl,temp,temp,lev,x-tx-1); //减一,那一步是最以下的塔的移动 else dfs(temp,fr,fr,lev,x-tx-1); } } int main() { got(); int T; cin>>T; while(T--) { long long n,m; cin>>n>>m; if(m<=(f[n]-1)/2) dfs('A','C','A',n,m); else dfs('A','C','C',n,m-(f[n]-1)/2); vectora,b,c; for(int i=n;i>=1;i--) { if(get[i]=='A')a.push_back(i); else if(get[i]=='B')b.push_back(i); else c.push_back(i); } cout<

汉若塔IX hdu2175,经典汉若塔问题上问第M次移动的是几号盘。

思路:同理,第n个盘之前,必先移动前n-1个,再移动第n号,再移动前n-1个,依次。所以二分法查找,在“中间”那个移动的酒在那一个盘了。

#include
using namespace std;
long long f[65];  //2^i次的值
void got()       //预处理的f[i]; 注意点:用1<>n>>m&&(n||m))
    {
        while(m!=f[n-1])
        {
            if(m<=f[n-1]-1)
             ;
            else
              m=m-f[n-1];
            n--;
        }
        cout<


汉若塔X  hdu2511  求第m次移动是把几号盘从哪个塔到哪个塔移动。

第九代的扩展。

思路:做到这里,每步的移动已经一清二楚了。还是那颗树,“左中右”遍历序列便是全部状态。因为一共就6种可能移动法。

每次移动后知道下一步的移动。

依然採用二分寻根法。详见代码:

#include
#include
using namespace std;
long long f[65];  //2^i次的值
void got()       //预处理的f[i]; 注意点:用1<

{ f[0]=1;f[1]=2; for(int i=2;i<65;i++) f[i]=f[i-1]*2; } string getnext(string s,int id) //状态转移 { if(s=="AC") { if(id==0)return "AB"; else return "BC"; } else if(s=="AB") { if(id==0)return "AC"; else return "CB"; } else if(s=="CB") { if(id==0)return "CA"; else return "AB"; } else if(s=="CA") { if(id==0)return "CB"; else return "BA"; } else if(s=="BA") { if(id==0)return "BC"; else return "CA"; } else if(s=="BC") { if(id==0)return "BA"; else return "AC"; } } int main() { got(); int T; cin>>T; long long n,m; while(T--) { cin>>n>>m; string s="AC"; while(m!=f[n-1]) { if(m<=f[n-1]-1) { s=getnext(s,0); } else { s=getnext(s,1); m=m-f[n-1]; } n--; } if(s=="AB") cout<


你可能感兴趣的:(汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。)