八数码这个游戏估计大多数人都玩过。就是给你一个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");
}
}