题意:给你一个串,仅含有a~g,且每个字母只出现最多一次。和一个光标初始位置,以及一个目标串,问你最少要多少的代价变化成目标串。
有五种操作:在光标前添加一个未出现过的字母,代价1。
删除光标前或者光标后的字母,代价1。
光标左移或者右移,代价0.5。
哈希,把串弄成一个八进制数,加上一个光标位置,状态数不超过8^8。
直接跑dijkstra即可。
要注意初始化的时候,可以单独记一个数组,表示用过的状态,仅仅重置这些状态,防止初始化复杂度过高。
#include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; char s1[10],s2[10]; int pp,len1,len2,d[17000000],pw[10]; bool vis[17000000],cant[8]; int st[17000000],En; struct Node{ int u,d; Node(const int &u,const int &d){ this->u=u; this->d=d; } Node(){} }; bool operator < (const Node &a,const Node &b){ return a.d>b.d; } priority_queue<Node>Heap; int main(){ // freopen("j.in","r",stdin); memset(d,0x7f,sizeof(d)); pw[0]=1; for(int i=1;i<=8;++i){ pw[i]=pw[i-1]*8; } while(scanf("%s%d%s",s1,&pp,s2)!=EOF){ memset(cant,0,sizeof(cant)); bool flag=1; while(!Heap.empty()){ Heap.pop(); } En=0; int U=0,len1=strlen(s1),len2=strlen(s2); for(int i=0;i<len2;++i){ if(cant[s2[i]-'a'+1]){ flag=0; break; } cant[s2[i]-'a'+1]=1; } if(!flag){ puts("-1"); continue; } for(int i=0;i<len1;++i){ U=U*8+s1[i]-'a'+1; } U=U*8+pp; int goal=0; for(int i=0;i<len2;++i){ goal=goal*8+s2[i]-'a'+1; } Heap.push(Node(U,0)); d[U]=0; st[++En]=U; while(!Heap.empty()){ Node now=Heap.top(); Heap.pop(); if(!vis[now.u]){ if(now.u/8==goal){ break; } vis[now.u]=1; int U=now.u; int len=0; int gbp=U%8; U/=8; memset(cant,0,sizeof(cant)); // char S[10]; while(U){ cant[U%8]=1; // S[len++]=U%8+'a'-1; ++len; U/=8; } // for(int i=0;i<len;++i){ // putchar(S[i]); // } // puts(""); //plus if(len<7){ U=now.u; U-=(U%pw[len-gbp+1]); U*=8; U+=(now.u%pw[len-gbp+1]); for(int i=1;i<=7;++i){ if(!cant[i]){ int tU=U+i*pw[len-gbp+1]; ++tU; if(d[tU]>d[now.u]+2){ d[tU]=d[now.u]+2; Heap.push(Node(tU,d[tU])); st[++En]=tU; } } } } //delete if(len>0){ if(gbp>0){ U=now.u%pw[len-gbp+1]; int tmp=now.u; tmp/=pw[len-gbp+2]; tmp*=pw[len-gbp+1]; U+=tmp; --U; if(d[U]>d[now.u]+2){ d[U]=d[now.u]+2; Heap.push(Node(U,d[U])); st[++En]=U; } } if(gbp<len){ U=now.u%pw[len-gbp]; int tmp=now.u; tmp/=pw[len-gbp+1]; tmp*=pw[len-gbp]; U+=tmp; if(d[U]>d[now.u]+2){ d[U]=d[now.u]+2; Heap.push(Node(U,d[U])); st[++En]=U; } } } //move if(gbp>0){ if(d[now.u-1]>d[now.u]+1){ d[now.u-1]=d[now.u]+1; Heap.push(Node(now.u-1,d[now.u-1])); st[++En]=now.u-1; } } if(gbp<len){ if(d[now.u+1]>d[now.u]+1){ d[now.u+1]=d[now.u]+1; Heap.push(Node(now.u+1,d[now.u+1])); st[++En]=now.u+1; } } } } printf("%.1f ",(double)(*min_element(d+goal*8,d+goal*8+8))*0.5); for(int i=1;i<=En;++i){ d[st[i]]=2000000000; vis[st[i]]=0; } } return 0; }