hdu-1430 魔板 康拓展开+映射优化
给定三种操作,将排列A转化为排列B,求最少步骤。
这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串呢?因为每一个数字都是等价的,我们可以把2映射为1,3映射成2,以此类推。这样就可以用"12345678"跑出来的操作序列了。
#include <iostream> #include <iomanip> #include <set> #include <cmath> #include <string> #include <algorithm> #include <queue> #include <vector> #include <map> #define LL long long using namespace std; class cantor { public: #define siz 8 char c[siz]= {'1','2','3','4','5','6','7','8'}; LL w[siz]; bool vis[siz]; cantor() { w[0]=1; for(int i=1; i<siz; i++) w[i]=w[i-1]*i; } void init() { for(int i=0; i<siz; i++) vis[i]=false; } LL makeCanto(string s) { init(); LL rec=0; for(int i=0; i<siz; i++) { int d=0; for(int j=0; j<siz; j++) { if(vis[j]) continue; if(c[j]!=s[i])d++; else { vis[j]=true; break; } } rec+=w[siz-i-1]*d; } return rec; } string recover(LL val) { init(); string s=""; for(int i=siz-1; i>=0; i--) { LL te=val/w[i]; val%=w[i]; for(int j=0,cnt=-1; j<siz; j++) { if(vis[j])continue; else cnt++; if(cnt==te&&!vis[j]) { s+=c[j]; vis[j]=true; break; } } } return s; } } fix; struct ax { int _1,_2; ax(int __1,int __2) { _1=__1; _2=__2; } friend bool operator < (ax a,ax b) { if(a._1==b._1) return a._2<b._2; return a._1<b._2; } }; LL n,m; bool vis[50000]; bool f; struct node { LL v; string a; node(LL V,string A) { v=V; a=A; } }; map<int,string> ans; void bfs(int fr) { queue<node> q; node ini=node(fr,""); q.push(ini); fill(vis,vis+50000,false); vis[fr]=true; while(!q.empty()) { node now=q.front(); q.pop(); ans[now.v]=now.a; string nows=fix.recover(now.v); string nx; //A nx=nows; for(int i=0; i<4; i++) swap(nx[i],nx[i+4]); if(!vis[fix.makeCanto(nx)]) vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"A")); //B for(int i=0; i<4; i++) nx[(i+1)%4]=nows[i],nx[4+(i+1)%4]=nows[4+i]; if(!vis[fix.makeCanto(nx)]) vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"B")); //C nx=nows; nx[1]=nows[5];nx[2]=nows[1]; nx[6]=nows[2];nx[5]=nows[6]; if(!vis[fix.makeCanto(nx)]) vis[fix.makeCanto(nx)]=true,q.push(node(fix.makeCanto(nx),now.a+"C")); } } int main() { cin.sync_with_stdio(false); string s1,s2; /* string nows,nx; cin>>nows; nx=nows; nx[1]=nows[5];nx[2]=nows[1]; nx[6]=nows[2];nx[5]=nows[6]; nows=nx; nx[1]=nows[5];nx[2]=nows[1]; nx[6]=nows[2];nx[5]=nows[6]; cout<<nx<<endl; */ string fuck="12348765"; bfs(fix.makeCanto(fuck)); while(cin>>s1>>s2) { reverse(s1.begin()+4,s1.end()); reverse(s2.begin()+4,s2.end()); for(int i=0;i<8;i++) { int d; for(int j=0;j<8;j++) if(s2[i]==s1[j]) d=j; s2[i]=fuck[d]; } cout<<ans[fix.makeCanto(s2)]<<endl; } }