poj 1077 Eight 【经典八数码问题】


Accepted 3164K 219MS G++ 3644B



经典题感觉就是不一样。

总是花了很长时间浪费在一些无关紧要的地方,把方向理解错了,正好相反的,调了N久。

后来输出的时候,都往反方向输出A了。

用康托展开做哈希函数,直接BFS就可以了

#include<iostream>
#include<cstring>
using namespace std;

int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
void swap(int &a, int &b)
{
     int t=a; a=b; b=t;
}
int cantor(int x)
{
    int a[10]={0};
    for(int i=9; i>=1; i--)
    {
            a[i]=x%10;
            x/=10;
    }
    int ans=0;
    for(int i=1; i<=9; i++)
    {
            int c=0;
            for(int j=i+1; j<=9; j++)
                    if(a[j]<a[i])c++;
            ans+=c*fac[a[i]-1];      
    }
    return ans;
}

struct type
{
       int last;
       int now;
       int move;
}Q[362885];

bool used[362885]={0};

bool change(int &x, int ch)//方向理解反了,调r时其实是调l
{
     int status[4][4],temp=x;
     int row,column;
     for(int i=3; i>=1; i--)
             for(int j=3; j>=1; j--)
             {
                     status[i][j]=temp%10;
                     temp/=10;
                     if(status[i][j]==9)
                     {  row=i; column=j; }            
             }
     switch(ch)
     {
               case 1: if(column==1)return false;  //r
                         swap(status[row][column], status[row][column-1]); break;
               case 2: if(column==3)return false;  //l
                         swap(status[row][column], status[row][column+1]);break;
               case 3: if(row==3)return false;     //u
                         swap(status[row][column], status[row+1][column]); break;
               case 4: if(row==1) return false;    //d
                         swap(status[row][column], status[row-1][column]); break;
     }
     temp=0;
     for(int i=1; i<=3; i++)
     for(int j=1; j<=3; j++)
             temp=temp*10+status[i][j];
     x=temp;
     return true;
}

int main()
{
    int now=0;
    int goal=0;
    char t;
    for(int i=1; i<=9; i++)
    {
            cin>>t;
            if(t=='x')t='9';
            now=now*10+int(t-'0');
    }       
    int l=1,r=1;
    Q[1].last=0; Q[1].now=now;
    int x=cantor(now);
    used[x]=1;
    bool find=false;
    while(l<=r&&find==false&&r<=362881)
    {
          int num=Q[l].now, can;
          int temp;
          //system("pause");
          for(int i=1; i<=4; i++)
          {
                  temp=num;
                  if(change(temp,i))
                  {
                                   can=cantor(temp);
                                   if(!used[can])
                                   {
                                                 used[can]=true;     
                                                 r++;
                                                 Q[r].now=temp;
                                                 Q[r].last=l;
                                                 Q[r].move=i;
                                   }
                                   if(can==goal){find=true; break; }
                  }
          }
         l++;
    }         
   
    if(find==false)cout<<"unsolvable"<<endl;
    else
    {
         int ans[1000];  int len=0;
        
         for( ;r!=1; )
         {
             
              len++;
              ans[len]=Q[r].move;
              r=Q[r].last;
         }
         for(int i=len; i>=1; i--)
         {
                 switch(ans[i])
                 {
                                 case 2:cout<<'r';break;//调一下输出顺序A了
                                 case 1:cout<<'l';break;
                                 case 4:cout<<'u';break;
                                 case 3:cout<<'d';break;
                 }
         }
     cout<<endl;   
    }
   
    system("pause");
    return 0;
}

posted on 2010-08-20 11:04 田兵 阅读(337) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

常用链接

留言簿(2)

随笔分类(65)

随笔档案(65)

文章档案(2)

ACM

搜索

积分与排名

最新随笔

最新评论

阅读排行榜