uvaoj10085

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",&copy[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;
 }


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值