UVAoj10085
目前 隐式图 搜索,就三个步骤, 删 ,查 , 加。
考点 就在于 查的效率(用什么方法去判断重复),加的条件(什么情况下可以添加,这个题就是不超界,然后不重复就可以了)。
这个题又是一个练手的题,可以一试。
有个细节,就是向那个方向走要对应上。
--------------------------------------------------------------------------------------
#include<stdio.h>
#include<string.h>
typedef struct
{
int s[9];
int par;
char d;
}node;
node st[1000000];
int copy[9];
int d[4][2] ={ {-1,0},{1,0},{0,-1},{0,1}};
char dr[4] = {'U','D','L','R'};
int head[1000003],next[1000000];
int hash(node &p)
{
int v = 0,i;
for(i=0;i<9;i++)
{
v = v*10 +p.s[i];
}
return v%1000003;
}
int try_to_insert(int n)
{
int h = hash(st[n]);
int u = head[h];
while(u)
{
if(memcmp(st[u].s,st[n].s,sizeof(st[n].s))==0)
return 0;
u = next[u];
}
next[n] = head[h];
head[h] = n;
return 1;
}
int bfs()
{
memset(head,0,sizeof(head));
int i;int front=0,rear=0;
int t,x,y,m1,m2;
rear++;
memcpy(st[front].s, copy , sizeof(copy));
st[0].par = 0;
while(front < rear)
{
for(m1=0;m1<9;m1++)
if(st[front].s[m1] == 0)break;
memcpy(copy , st[front].s, sizeof(copy));
for(i=0;i<4;i++)
{
x = m1/3 + d[i][0];
y = m1%3 + d[i][1];
if(x>=0 && y>=0 && x<3 && y<3)
{
m2 = x*3 + y;
t = copy[m1];
copy[m1] = copy[m2];
copy[m2] = t;
memcpy(st[rear].s, copy , sizeof(copy));
if(try_to_insert(rear))
{
st[rear].par = front;
st[rear].d = dr[i];
rear++;
}
t = copy[m1];
copy[m1] = copy[m2];
copy[m2] = t;
}
}
front++;
}
return rear;
}
void print(int i)
{
if(i != 0)
{
print(st[i].par);
printf("%c",st[i].d);
}
}
int main()
{
int n , i ,r ,count=1;
char c;
scanf("%d",&n);
while(n--)
{
for(i=0;i<9;i++)
scanf("%d",©[i]);
r = bfs();
printf("Puzzle #%d\n", count ++);
for(i=0;i<9;i++)
{
if(i%3<2)
printf("%d ",st[r-1].s[i]);
else
printf("%d",st[r-1].s[i]);
if((i+1)%3==0)printf("\n");
}
print(r-1);
printf("\n\n");
}
return 0;
}