HDU-3567 Eight II

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=3567

题意:

八数码问题,就是终止情况不固定。

思路:

类似于魔板那题的解法,重点是状态的转换,然后打表解题即可。代码丑陋,写的暴力了

代码:

#define N 501234

char ss[10];
struct node
{
    char str[10];
    int pos;
    int index;
};
struct res
{
    int now,fa;
}res[10][N];
int vis[11][N];
int  fac[] = {1,1,2,6,24,120,720,5040,40320};
int over,cnt;
int ans[N];
int KT(char ss[])
{
    int i, j, t, sum;
    int s[10];
    for(i=0;i<9;i++)
    {
        if(ss[i]=='X')
            s[i]=0;
        else
            s[i]=ss[i]-'0';
    }
    sum = 0;
    for (i=0; i<9; i++)
    {
        t = 0;
        for (j=i+1; j<9; j++)
            if (ss[j] < ss[i])
                t++;
        sum += t*fac[9-i-1];
    }
    return sum+1;
}
bool bfs(int now)
{
    char c;
    queue<node> q;
    while(!q.empty())q.pop();
    over = KT(ss);
    node g,h;
    for(int i=0;i<8;i++)
        g.str[i]=i+1+'0';
    for(int i=7;i>=now;i--)
        g.str[i+1]=g.str[i];
    g.str[now]='X';g.str[9]='\0';
    g.pos=0;g.index=now;
    int t=KT(g.str);
    vis[now][t] = 0;
    q.push(g);
    cnt=1;
    while(!q.empty())
    {
        g=q.front();q.pop();
        int t = KT(g.str);
        h=g;
        if(h.index<6)
        {
            c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;
            h.index+=3;
            res[now][cnt].now=2;res[now][cnt].fa=h.pos;h.pos=cnt;cnt++;
            int t=KT(h.str);
            if(vis[now][t]==-1)
            {
                vis[now][t]=cnt-1;
                q.push(h);
            }
        }
        h=g;
        if(h.index%3!=0)
        {
            c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;
            h.index--;
            res[now][cnt].now=3;res[now][cnt].fa=h.pos;h.pos=cnt;cnt++;
            int t=KT(h.str);
            if(vis[now][t]==-1)
            {
                vis[now][t]=cnt-1;
                q.push(h);
            }
        }
        h=g;
        if((h.index+1)%3!=0)
        {
            c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
            h.index++;
            res[now][cnt].now=4;res[now][cnt].fa=h.pos;h.pos=cnt;cnt++;
            int t=KT(h.str);
            if(vis[now][t]==-1)
            {
                vis[now][t]=cnt-1;
                q.push(h);
            }
        }
        h=g;
        if(h.index>2)
        {
            c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;
            h.index-=3;
            res[now][cnt].now=1;res[now][cnt].fa=h.pos;h.pos=cnt;cnt++;
            int t=KT(h.str);
            if(vis[now][t]==-1)
            {
                vis[now][t]=cnt-1;
                q.push(h);
            }
        }
    }
    return false;
}
int main()
{
    int i,j,k,kk,t,x,y,z;
    int num[11];
    #ifndef ONLINE_JUDGE
        freopen("test.txt","r",stdin);
    #endif
    memset(vis,-1,sizeof(vis));
    res[0][0].now=-1;bfs(0);
    res[1][0].now=-1;bfs(1);
    res[2][0].now=-1;bfs(2);
    res[3][0].now=-1;bfs(3);
    res[4][0].now=-1;bfs(4);
    res[5][0].now=-1;bfs(5);
    res[6][0].now=-1;bfs(6);
    res[7][0].now=-1;bfs(7);
    res[8][0].now=-1;bfs(8);
    scanf("%d",&k);
    kk=0;
    while(k--)
    {
        scanf("%s",ss);
        for(i=0,j=0;i<9;i++)
        {
            if(ss[i]=='X')
                x=i;
            else
                num[ss[i]-'0']=j++;
        }
        scanf("%s",ss);
        for(i=0;i<9;i++)
        {
            if(ss[i]=='X')continue;
            else ss[i]=num[ss[i]-'0']+'1';
        }
        t = KT(ss);
        over=0;
        printf("Case %d: ",++kk);
        t = vis[x][t];
        while(res[x][t].now!=-1)
        {
            ans[over++]=res[x][t].now;
            t=res[x][t].fa;
        }
        printf("%d\n",over);
        for(i=over-1;i>=0;i--)
        {
            if(ans[i]==1)printf("u");
            if(ans[i]==2)printf("d");
            if(ans[i]==3)printf("l");
            if(ans[i]==4)printf("r");
        }
        printf("\n");
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值