zoukankan      html  css  js  c++  java
  • hdoj1043 Eight(逆向BFS+打表+康拓展开)

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

    思路:

    由于自己对康拓展开用的太少,看到这个题没想到康拓展开,最开始打算直接转换为数字,但太占内存了,又想到可以将状态存进set,后来查了一下发现原来是考察康拓展开。另外就是需要打表预处理,这样快很多。BFS部分就是已知终点,从终点逆向搜索,并存每个状态的上一个状态以及操作,以便输出。

    坑点:输入是多组输入,POJ那道题才是一组输入,卡在这一上午T_T。

       有一组输入为12345678x,需要特殊处理,不能不输出,可以输出“lr”。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn=1e6+5;
     5 struct node{
     6     char a[9];
     7     int x,y;
     8     int cnt;
     9 }tmp;
    10 
    11 int fac[9];
    12 int vis[maxn];
    13 char path[maxn];
    14 int pre[maxn];
    15 int go[4][2]={-1,0,0,1,1,0,0,-1};
    16 
    17 void init(){
    18     fac[0]=fac[1]=1;
    19     for(int i=2;i<9;i++) fac[i]=fac[i-1]*i;
    20 }
    21 
    22 int cantour(char *s){
    23     int ans=0,k;
    24     for(int i=0;i<8;i++){
    25         k=0;
    26         for(int j=i+1;j<9;j++)
    27             if(s[j]<s[i]) k++;
    28         ans+=k*fac[8-i];
    29     }
    30     return ans;
    31 }
    32 
    33 void bfs(){
    34     queue<node> q;
    35     for(int i=0;i<8;i++)
    36         tmp.a[i]=i+1+'0';
    37     tmp.a[8]='0';
    38     tmp.x=2,tmp.y=2,tmp.cnt=cantour(tmp.a);
    39     vis[tmp.cnt]=1;
    40     q.push(tmp);
    41     path[tmp.cnt]=-1;
    42     while(!q.empty()){
    43         node now=q.front();q.pop();
    44         int nx=now.x,ny=now.y,ncnt=now.cnt;
    45         for(int i=0;i<4;i++){
    46             int xx=nx+go[i][0],yy=ny+go[i][1];
    47             if(xx<0||xx>2||yy<0||yy>2) continue;
    48             strcpy(tmp.a,now.a);
    49             swap(tmp.a[nx*3+ny],tmp.a[xx*3+yy]);
    50             tmp.x=xx,tmp.y=yy,tmp.cnt=cantour(tmp.a);
    51             if(!vis[tmp.cnt]){
    52                 vis[tmp.cnt]=1;
    53                 pre[tmp.cnt]=ncnt;
    54                 if(i==0) path[tmp.cnt]='d';
    55                 else if(i==1) path[tmp.cnt]='l';
    56                 else if(i==2) path[tmp.cnt]='u';
    57                 else path[tmp.cnt]='r';
    58                 q.push(tmp);
    59             }
    60         }
    61     }
    62 }
    63 
    64 void print(int f){
    65     while(path[f]!=-1){
    66         printf("%c",path[f]);
    67         f=pre[f];
    68     }
    69     printf("
    ");
    70 }
    71 
    72 int main(){
    73     char c[9],ch;
    74     int f;
    75     init();
    76     bfs();
    77     while(scanf(" %c",&ch)!=EOF){
    78         if(ch=='x') c[0]='0';
    79         else c[0]=ch;
    80         for(int i=1;i<9;i++){
    81             scanf(" %c",&ch);
    82             if(ch=='x') c[i]='0';
    83             else c[i]=ch;
    84         }
    85         f=cantour(c);
    86         if(path[f]==-1) printf("lr
    ");
    87         else if(!vis[f]) printf("unsolvable
    ");
    88         else print(f);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    sql server 分组,取每组的前几行数据
    安装vim的ycm
    Linux下管道重定向使用以及Shell编程(操作系统)
    VirtualBox安装及Linux基本操作(操作系统实验一)
    创建表并查看表(数据库实验一)
    SQL SERVER安装(2008)
    ADT图及图的实现及图的应用
    并查集实现及使用
    堆及堆的应用/单调队列/堆排序
    AVL树/线索二叉树
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10357366.html
Copyright © 2011-2022 走看看