题意:有2个字符串,求用下面2种操作将后一个字符串转化成前一个字符串的最小操作次数
1.将一位数字改变为另一个数字
2.将所有一种数字变为另一种数字
建立一个从1-6到其他数字的映射关系,用6位6进制保存
用bfs跑出映射的最小操作数
再对字符串用所有映射计算答案,取最小的一个
#include<bits/stdc++.h> using namespace std; const int N=110+5; const int M=5e4+5; const int INF=0x3f3f3f3f; int dp[M]; int a[6],b[6]; char x[N],y[N]; int s[6],c[6][6]; int sum(int *t) { int ans=0; for(int i=0;i<6;i++) ans=ans*6+t[i]; return ans; } void change(int x,int *t) { for(int i=5;i>=0;i--) { t[i]=x%6; x/=6; } } void bfs() { memset(dp,0x3f,sizeof(dp)); for(int i=0;i<6;i++) a[i]=i; int t=sum(a);dp[t]=0; queue<int> que; que.push(t); while(!que.empty()) { int tem=que.front();que.pop(); change(tem,a); for(int i=0;i<6;i++) for(int j=0;j<6;j++) { memcpy(b,a,sizeof(a)); for(int k=0;k<6;k++) if (b[k]==i) b[k]=j; int ss=sum(b); if (dp[ss]>dp[tem]+1) { dp[ss]=dp[tem]+1; que.push(ss); } } } } int main() { bfs(); while(scanf("%s%s",x,y)!=EOF) { int len=strlen(x); memset(s,0,sizeof(s)); memset(c,0,sizeof(c)); for(int i=0;i<len;i++) { int t1=y[i]-'1',t2=x[i]-'1'; s[t1]++;c[t1][t2]++; } int ans=INF; for(int i=0;i<M;i++) { change(i,a); int tem=dp[i]; for(int j=0;j<6;j++) tem+=s[j]-c[j][a[j]]; ans=min(ans,tem); } printf("%d ",ans); } return 0; }