poj 1184 聪明的打字员

本文提供了一种针对POJ 1184问题的有效BFS算法解决方案,通过细致的代码实现与状态压缩技巧,优化了搜索过程,避免了不必要的重复检查,显著提高了效率。

http://poj.org/problem?id=1184

bfs  但是如果不加好的优化是过不了的 好像很多人多看了一分解析 我也是

很详细 下面是链接:

http://blog.youkuaiyun.com/lyy289065406/article/details/6648695

非常不错的解题报告

我的代码 很丑:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#define LL long long

using namespace std;

const int N=1000005;
const int MAX=0x3f3f3f3f;
bool visited[7][1000][100];
int num[1000][100];
int f[700000];
int real[1000];
struct node
{
    int x,y,z,k;
}que[N];
int I,J;
int a[7];
int b[7];
int c[7];
bool had[7];
int st,nd;
void dfs(int l,int sum)
{
    if(l==7)
    {
        real[I]=sum;
        f[sum]=I++;
        return ;
    }
    for(int i=1;i<=6;++i)
    {
        if(!had[i])
        {
            had[i]=true;
            dfs(l+1,sum*10+i);
            had[i]=false;
        }
    }
}
int k1,k2;
void swap1(int x,int y,int z,int k)
{
    k1=y/a[x]%10;
    k2=y/100000;
    y=y-(k1*a[x]-k2*a[x])-(k2-k1)*100000;
    if(visited[x][f[y]][k]==true)
    return ;
    visited[x][f[y]][k]=true;
    num[f[y]][k]=min(num[f[y]][k],z+1);
    que[J].x=x;que[J].y=y;que[J].z=z+1;que[J].k=k;++J;
}
void swap6(int x,int y,int z,int k)
{
    k1=y/a[x]%10;
    k2=y%10;
    y=y-(k1*a[x]-k2*a[x])-(k2-k1);
    k=k|(1<<5);//cout<<x<<" "<<y<<" "<<z<<" "<<k<<endl;
    if(visited[x][f[y]][k]==true)
    return ;
    visited[x][f[y]][k]=true;
    num[f[y]][k]=min(num[f[y]][k],z+1);
    que[J].x=x;que[J].y=y;que[J].z=z+1;que[J].k=k;++J;
}
void cur_left(int x,int y,int z,int k)
{
    --x;
    if(visited[x][f[y]][k]==true)
    return ;
    visited[x][f[y]][k]=true;
    num[f[y]][k]=min(num[f[y]][k],z+1);
    que[J].x=x;que[J].y=y;que[J].z=z+1;que[J].k=k;++J;
}
void cur_right(int x,int y,int z,int k)
{
    k=k|(1<<x);
    ++x;
    if(visited[x][f[y]][k]==true)
    return ;
    visited[x][f[y]][k]=true;
    num[f[y]][k]=min(num[f[y]][k],z+1);
    que[J].x=x;que[J].y=y;que[J].z=z+1;que[J].k=k;++J;
}
void bfs()
{
    int x,y,z,k;
    while(I<J)
    {
        x=que[I].x;y=que[I].y;
        z=que[I].z;k=que[I].k;++I;
        if(x>1)
        swap1(x,y,z,k);
        if(x<6)
        swap6(x,y,z,k);
        if(x>1)
        cur_left(x,y,z,k);
        if(x<6)
        cur_right(x,y,z,k);
    }
}
void begin()
{
    a[6]=1;
    for(int i=5;i>=1;--i)
    a[i]=a[i+1]*10;
    memset(had,false,sizeof(had));
    I=0;
    dfs(1,0);
    I=J=0;
    for(int i=0;i<720;++i)
    for(int j=0;j<64;++j)
    num[i][j]=MAX;
    memset(visited,false,sizeof(visited));
    int s=123456;
    visited[1][f[s]][1]=true;
    num[f[s]][1]=0;
    que[J].x=1;que[J].y=s;que[J].z=0;que[J].k=1;++J;
    bfs();
}
int Fmin(int i,int j)
{
    int temp=nd;
    for(int l=6;l>=1;--l)
    {
        c[l]=b[i%10];
        a[l]=temp%10;
        i=i/10;temp=temp/10;
    }
    int k=0;
    for(int l=1;l<=6;++l)
    {
        if(a[l]!=c[l])
        {
            if((j&1)==0)
            return MAX;
            k+=abs(a[l]-c[l]);
        }
        j=j>>1;
    }
    return k;
}
int main()
{
   //freopen("data","r",stdin);
    begin();
    while(scanf("%d %d",&st,&nd)!=EOF)
    {
        int ans=MAX;
        for(int i=6;i>=1;--i)
        {
            b[i]=st%10;
            st=st/10;
        }
        for(int i=0;i<720;++i)
        {
            for(int j=0;j<64;++j)
            {
                if(num[i][j]!=MAX)
                {
                    ans=min(ans,num[i][j]+Fmin(real[i],j));
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/liulangye/archive/2012/08/22/2650783.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值