hdu 3567 康托展开 +BFS

来源:互联网 发布:淘宝信用贷款逾期20天 编辑:程序博客网 时间:2024/05/18 18:04

HDU 1430 DFS + 康托展开 + 映射处理 +预处理!

http://blog.csdn.net/little_boy_z/article/details/78428300


和hdu1430很类似,模仿着来即可。

主要会用康托就好了


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1000000005
using namespace std;
int ed;
int fac[3][3]= {{1,1,2},{6,24,120},{720,5040,40320}};//计算康拓值
struct node
{
    int Map[3][3];
    int x,y;
    int Hash;
    bool cheak()
    {
        if(x>=0&&x<3&&y>=0&&y<3)
            return true ;
        return false ;
    }
} u,uu,v;
int vis[9][400000];//标记
int pri[9][400000];//路径
int dir[4][2]= {{1,0},{0,-1},{0,1},{-1,0}};


int get_hash(int maze[3][3])  //计算康拓值
{
    int ret=0;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        {
            int cnt=0;
            for(int a=0; a<i; a++)
                for(int b=0; b<3; b++)
                    if(maze[a][b]>maze[i][j])
                        cnt++;
            for(int b=0; b<j; b++)
                if(maze[i][b]>maze[i][j])
                    cnt++;
            ret+=cnt*fac[i][j];
        }
    return ret;
}


char ch[5]= {"dlru"};
//输出路径
void print(int i)
{
    int st=ed;


    int cnt=0,ans[1000];


    while(pri[i][st]!=-2)
    {
        ans[cnt++]=vis[i][st];
        st=pri[i][st];
    }
    printf("%d\n",cnt);
    for(int i=cnt-1; i>=0; i--)
        printf("%c",ch[ans[i]]);
    printf("\n");
    return ;
}


void bfs(int kind)
{
    queue<node>que;
    que.push(u);
    pri[kind][u.Hash]=-2;
    while(!que.empty())
    {
        uu=que.front();
        que.pop();
        for(int i=0; i<4; i++)
        {
            v=uu;
            v.x+=dir[i][0];
            v.y+=dir[i][1];
            if(v.cheak())
            {
                swap(v.Map[v.x][v.y],v.Map[uu.x][uu.y]);
                v.Hash=get_hash(v.Map);
                if(pri[kind][v.Hash]==-1)
                {
                    pri[kind][v.Hash]=uu.Hash;
                    vis[kind][v.Hash]=i;
                    que.push(v);
                }
            }
        }
    }
}


void Init(char *str,int kind)
{
    int k=0;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        {
            if(str[k]=='X')
                u.Map[i][j]=0;
            else
                u.Map[i][j]=str[k]-'0';
            k++;
        }
    u.x=kind/3;
    u.y=kind%3;
    u.Hash=get_hash(u.Map);
    bfs(kind);
}


int main()
{
    int t;
    int tt=1;
    //预处理
    memset(pri,-1,sizeof(pri));
    Init("X12345678",0);
    Init("1X2345678",1);
    Init("12X345678",2);
    Init("123X45678",3);
    Init("1234X5678",4);
    Init("12345X678",5);
    Init("123456X78",6);
    Init("1234567X8",7);
    Init("12345678X",8);
    scanf("%d",&t);
    while(t--)
    {
        char s1[10],s2[10];
        scanf("%s%s",s1,s2);
        int a[3][3],b[3][3],pos,c[9],k=1;
        for(int i=0; i<9; i++)
        {
            if(s1[i]=='X')
            {
                c[0]=0;
                pos=i;
            }
            else
                c[s1[i]-'0']=k++;
        }
        for(int i=0; i<9; i++)
            b[i/3][i%3]=(s2[i]=='X'?c[0]:c[s2[i]-'0']);
        ed=get_hash(b);
        printf("Case %d: ",tt++);
        print(pos);
    }
    return 0;
}

原创粉丝点击