zoukankan      html  css  js  c++  java
  • HDU 1043 Eight(反向BFS+打表+康托展开)

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

    题目大意:传统八数码问题

    解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各个状态记录下来,因为数字太大所以用康托展开将数字离散化。

    代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<string>
     6 #include<queue>
     7 using namespace std;
     8 typedef long long ll; 
     9 const int N=4e5+5;
    10 
    11 int vis[N];
    12 string path[N];
    13 char map[15];
    14 char index[5]="udrl";//因为是逆向所以方向要反一下 
    15 int d[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
    16 int fac[15]={1,1,2,6,24,120,720,5040,40320};
    17 
    18 struct node{
    19     char num[10];
    20     int pos;
    21     string path;
    22 }pre,now;
    23 
    24 //求康托展开值 
    25 int cantor(char s[]){
    26     int sum=0;
    27     int n=strlen(s);
    28     for(int i=0;i<n;i++){
    29         int cnt=0;
    30         for(int j=i+1;j<n;j++){
    31             if(s[i]>s[j])
    32                 cnt++;
    33         }
    34         sum+=cnt*fac[n-i-1];
    35     }
    36     return sum+1;
    37 }
    38 //从12345678x逆向BFS打表 
    39 void bfs(){
    40     queue<node>q;
    41     now.pos=8;
    42     for(int i=0;i<8;i++)
    43         now.num[i]=i+1+'0';
    44     now.num[8]='0';
    45     now.num[9]='';
    46     q.push(now);
    47     while(!q.empty()){
    48         pre=q.front();
    49         q.pop();
    50         int pos=pre.pos;
    51         //转换成二维坐标 
    52         int x=pos/3;
    53         int y=pos%3;    
    54         for(int i=0;i<4;i++){
    55             int xx=x+d[i][0];
    56             int yy=y+d[i][1];
    57             if(xx<0||yy<0||xx>2||yy>2)
    58                 continue;
    59             //转换回一维坐标 
    60             int new_pos=xx*3+yy;
    61             now=pre;
    62             swap(now.num[pos],now.num[new_pos]);
    63             int tmp=cantor(now.num);
    64             if(!vis[tmp]){
    65                 now.pos=new_pos;
    66                 //index[i]要加在前面,反的嘛 
    67                 now.path=index[i]+now.path;
    68                 vis[tmp]=1;
    69                 //存储路径 
    70                 path[tmp]=now.path;
    71                 q.push(now);
    72             }
    73         }
    74     }
    75 }
    76 
    77 int main(){
    78     char c;
    79     bfs();
    80     while(cin>>c){
    81         //x转换成0便于康托展开 
    82         if(c=='x')
    83             map[0]='0';
    84         else
    85             map[0]=c;
    86         for(int i=1;i<9;i++){
    87             cin>>map[i];
    88             if(map[i]=='x')
    89                 map[i]='0';
    90         }
    91         int aim=cantor(map);
    92         if(vis[aim])
    93             cout<<path[aim]<<endl;
    94         else
    95             cout<<"unsolvable"<<endl;
    96     }
    97 }
  • 相关阅读:
    vue基础知识
    git的创建使用
    使用express搭建服务器框架
    日常训练
    今日收获
    今日收获
    今日收获
    今日收获
    今日收获
    今日收获
  • 原文地址:https://www.cnblogs.com/fu3638/p/7529246.html
Copyright © 2011-2022 走看看