UVALive

来源:互联网 发布:淘宝店铺资质显示51000 编辑:程序博客网 时间:2024/05/21 18:45

题意:给你长度为110以内的,由1~6的数字构成的字符串,求从start串到end串的最小操作次数,每次操作可以:

①将一个位置的字符,替换成一个字符。

②将一种类型的字符,替换成另一种类型。

题解:首先我们可以考虑,第一种操作肯定在第二种操作之后,假如我们先替换单个字符1为2,再将所有的替换为3,那么还不如直接先将所有的替换为3,再将1替换为3。所以可以知道,第二种操作是可以在第一种操作之前的,所以我们先预处理,第二种操作的转移到的所有情况的最小操作次数。然后考虑转移之后的单步需要的次数。

AC代码:

#include<stdio.h>#include<queue>#include<string.h>using namespace std;char s[115],e[115];int dp[600005];int state[15];int zy[15][15];void init(){int sum=0;for(int i=5;i>=0;i--)sum=sum*6+i;queue<int>que;que.push(sum);dp[sum]=0;while(!que.empty()){int k=que.front();que.pop();for(int i=0;i<6;i++)for(int j=0;j<6;j++){if(i==j)continue;int now=k;for(int g=0;g<6;g++)state[g]=now%6,now/=6;sum=0;for(int g=5;g>=0;g--){if(state[g]==i)state[g]=j;sum=sum*6+state[g];}if(dp[sum]!=-1)continue;dp[sum]=dp[k]+1;que.push(sum);}}}int main(){memset(dp,-1,sizeof(dp));init();while(~scanf("%s%s",e,s)){memset(zy,0,sizeof(zy));int l=strlen(s);for(int i=0;i<l;i++)zy[s[i]-'1'][e[i]-'1']++;int ans=10000;for(int i=0;i<600000;i++){if(dp[i]==-1)continue;int sum=0,k=i;for(int j=0;j<6;j++){int now=k%6;k/=6;sum+=zy[j][now];}ans=min(ans,l-sum+dp[i]);}printf("%d\n",ans);}}


原创粉丝点击