UVALive 7263 Today Is a Rainy Day

题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5275

题意:有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\n",ans);
    }
    return 0;
}

  

posted @ 2018-04-19 22:48  BK_201  阅读(146)  评论(0编辑  收藏  举报