Codeforces 93 C. Azembler
問題
26個のレジスタ(eax,ebx,……,ezx)をもつコンピュータがある。
- lea x, [y]
- lea x, [y + z]
- lea x, [k*y]
- lea x, [y + k*z]
(ただしx,y,zはレジスタ名、kは1,2,4,8の整数)
の4つの命令を使い、いずれかのレジスタにeax * nの値を作りたい。
そのために必要な命令数の最小値および、そのときの命令を一通りどれか出力せよ。
制約条件
n≦255
ソースコード
int n; void run(){ cin>>n; vi v(26); v[0]=1; queue<pair<int,vi> > q; map<vi,vi> prev; prev[v]=vi(26,0); q.push(mp(1,v)); bool found=0; while(!q.empty()){ int cur=q.front().first; v=q.front().second; q.pop(); if(v[cur-1]==n){ vector<string> ans; for(;prev[v][0]>0;v=prev[v], cur--){ vi p=prev[v]; rep(i,cur)rep(j,cur+1)rep(k,4){ if(v[cur-1]==p[i]+(p[j]<<k)){ stringstream ss; bool flag=0; ss<<"lea e"<<(char)('a'+cur-1)<<"x, ["; if(i!=cur-1){ flag=1; ss<<"e"<<(char)('a'+i)<<"x"; } if(j<cur){ if(flag)ss<<" + "; if(k)ss<<(1<<k)<<"*"; ss<<"e"<<(char)('a'+j)<<"x"; } ss<<"]"; ans.push_back(ss.str()); goto FOUND; } } FOUND:; } reverse(all(ans)); cout<<ans.size()<<endl; rep(i,ans.size())cout<<ans[i]<<endl; goto END; } if(!found)rep(i,cur+1)rep(j,cur+1)rep(k,4){ vi nxt=v; nxt[cur]=v[i]+(v[j]<<k); if(nxt[cur]>n||prev.count(nxt))continue; prev[nxt]=v; q.push(mp(cur+1,nxt)); if(nxt[cur]==n){ found=1; goto NEXT; } } NEXT:; } END:; }