• Eight


    Eight

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043/http://acm.split.hdu.edu.cn/showproblem.php?pid=1043

    IDA*

    八数码问题直接dfs/bfs,时间复杂度很高,需要一个很好的剪枝,使用IDA*。当前状态到达目标状态最短(理想)距离h是各个数字直接到达目的地,如果h+当前步数>最深搜索的步数,那么这种情况就不去考虑。对于判断八数码是否可解,需要用到逆序数的知识((╯‵□′)╯︵┻━┻这谁会知道啊):x的移动并不影响整个数列逆序数的奇偶性,也就是说若给定初始状态逆序数的奇偶性与目标状态不同,则unsolvable。去重用到了状态压缩,因为数字数量级为10^9,使用set/map存储状态。(坑点是多组数据,但是题目没说)

    代码如下:

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<set>
      5 using namespace std;
      6 const int standard=123456780;
      7 set<int>exist;
      8 int a[9],state[3][3],deep,sx,sy,step[1000];
      9 char c;
     10 int dx[]={0,0,-1,1};
     11 int dy[]={-1,1,0,0};
     12 char towards[]={'l','r','u','d'};
     13 int index;
     14 bool ok=0;
     15 int inversions(){//求逆序数
     16     int num=0;
     17     for(int i=0;i<9;++i)
     18     for(int j=i+1;j<9;++j)
     19     if(a[i]!=0&&a[j]!=0)
     20         if(a[j]<a[i])num++;
     21     return num;
     22 }
     23 int zip(){
     24     int s=0;
     25     for(int i=0;i<3;++i)
     26     for(int j=0;j<3;++j)
     27         s=s*10+state[i][j];
     28     return s;
     29 }
     30 int Astar(){//无视障碍物直接到达目的地所需步数
     31     int h=0;
     32     for(int i=0;i<3;++i)
     33     for(int j=0;j<3;++j){
     34         int num=state[i][j];
     35         if(num!=0){
     36             int x=(num-1)/3;
     37             int y=(num-1)%3;
     38             h+=abs(x-i)+abs(y-j);
     39         }
     40     }
     41     return h;
     42 }
     43 void IDAstar(int px,int py,int nowdeep){
     44     if(ok)return;
     45     int h=Astar();
     46     if(!h&&zip()==standard){
     47         ok=1;
     48         return;
     49     }
     50     if(nowdeep+h>deep)return;//A*估价函数
     51     for(int i=0;i<4;++i){
     52         int x=px+dx[i];
     53         int y=py+dy[i];
     54         if(0<=x&&x<3&&0<=y&&y<3){
     55             swap(state[px][py],state[x][y]);
     56             int s=zip();
     57             if(!exist.count(s)){
     58                 step[index++]=i;
     59                 exist.insert(s);
     60                 IDAstar(x,y,nowdeep+1);
     61                 if(ok)return;
     62                 exist.erase(s);
     63                 step[--index]=0;
     64             }
     65             swap(state[px][py],state[x][y]);
     66         }
     67     }
     68 }
     69 int main(void){
     70     char k;
     71     while(cin>>k){
     72         ok=0;
     73         index=0;
     74         for(int i=0;i<9;++i){
     75             if(i==0)c=k;
     76             else cin>>c;
     77             if('1'<=c&&c<='8')
     78                 a[i]=c-'0';
     79             else a[i]=0;
     80         }
     81         if(inversions()&1){//若有解,逆序数的奇偶性和standard相同
     82             cout<<"unsolvable"<<endl;
     83             continue;
     84         }
     85         for(int i=0;i<3;++i)
     86         for(int j=0;j<3;++j){
     87             state[i][j]=a[3*i+j];
     88             if(state[i][j]==0)
     89                 sx=i,sy=j;
     90         }
     91         int s=zip();
     92         if(s==standard){
     93             cout<<""<<endl;
     94             continue;
     95         }
     96         for(deep=1;!ok;++deep){
     97             exist.clear();
     98             exist.insert(s);
     99             IDAstar(sx,sy,0);
    100         }
    101         for(int i=0;i<index;++i)
    102             cout<<towards[step[i]];
    103         cout<<""<<endl;
    104     }
    105 }
  • 相关阅读:
    Redux API之applyMiddleware
    Redux API之combineReducers
    Redux API之creatStore
    Redux API之Store
    React-Redux之API
    ES6之6种遍历对象属性的方法
    React库protypes属性
    js立即执行函数
    Collection与Map总结
    02-再探MySQL数据库
  • 原文地址:https://www.cnblogs.com/barrier/p/5786017.html
Copyright © 2020-2023  润新知