hdu 1043 eight 八数码问题

八数码这个游戏估计大多数人都玩过。就是给你一个3*3的矩阵,有一个空格。你可以将这个空格左边、右边、上面、下面的数字移到这个空格。要你利用这个空格达到目标状态。


比如:

1 2 3             1 2 3                                                                   1 2 3

x 4 6    -->    7 4 6    --> ....                             目标状态:    4 5 6
7 5 8             x 5 8                                                                    7 8 x

   x down          x left              


其实比较正统的方法是用hash+A*算法。据说用IDA+曼哈顿距离会更快。以后再写吧...

下面用暴力打表搞定,hdu 62ms。个人感觉我的代码还是很好理解的。

输入事例:2 3 4 1 5 x 7 6 8


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define result 0
struct sss
{
    int pre,step;
    int op,pos;
    char sz[10];
};

int g_hash[362882];
sss que[362888];
int g_nn[10]={1,1,2,6,24,120,720,5040,40320};
char stard[10]="123456789";
int g_head,g_tail;
int up(char *pre,char *now,int pos)
{

    if(pos>5) return -1;
    
    strcpy(now,pre);
    now[pos]=now[pos+3];
    now[pos+3]='9';
    return pos+3;
}

int down(char *pre,char *now,int pos)
{
    if(pos<3) return -1;
    
    strcpy(now,pre);
    now[pos]=now[pos-3];
    now[pos-3]='9';
    return (pos-3);
}

int left(char *pre,char *now,int pos)
{
    if(pos%3==2) return -1;
    
    strcpy(now,pre);
    now[pos]=now[pos+1];
    now[pos+1]='9';
    return (pos+1);
}

int right(char *pre,char *now,int pos)
{
    if(pos%3==0) return -1;
    
    strcpy(now,pre);
    now[pos]=now[pos-1];
    now[pos-1]='9';
    return pos-1;
}

char res[5]="urld";
int (*g_func[4])(char *,char *,int)={up,right,left,down};

int calhash(char *num)
{
    int i,j,cnt;
    int sum=0;
    for(i=0;i<9;i++)
    {
        cnt=0;
        for(j=0;j<i;j++)
        {
            if(num[j]>num[i]) cnt++;
        }
        sum+=cnt*g_nn[i];
    }

    return sum;
}

void getresult(int iHash)
{
    int ind = g_hash[iHash];

    while(que[ind].op!=-1)
    {
        putchar(res[que[ind].op]);
        ind=que[ind].pre;
    }

    puts("");
}

void init()
{
    que[1].op=-1;
    que[1].step=0;
    que[1].pos=8;
    strcpy(que[1].sz,stard);
    int iHash = calhash(stard);
    g_hash[iHash]=1;
    
    int i,head=1;
    int tail=2;
    while(head<tail)
    {
        for(i=0;i<4;i++)
        {
            que[tail].pos=(*g_func[i])(que[head].sz,que[tail].sz,que[head].pos);
            if(que[tail].pos==-1) continue;
            iHash = calhash(que[tail].sz);
            if(g_hash[iHash]) continue;

            g_hash[iHash]=tail;
            que[tail].pre=head;
            que[tail].op=i;
            tail++;
        }

        head++;
    }
}

char input[50];
char stardin[20];
int main()
{
    freopen("test.txt","r",stdin);
    init();
    int i,j,iHash;
    while(gets(input))
    {
        for(i=0,j=0;input[i]&&j<9;i++)
        {
            if(input[i]=='x')
            {
                stardin[j]='9';
                j++;
            }
            else if(input[i]>='0'&&input[i]<='9')
            {
                stardin[j++]=input[i];
            }
        }

        iHash=calhash(stardin);
        if(g_hash[iHash])
        {
            getresult(iHash);
        }
        else puts("unsolvable");
    }
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值