zoukankan      html  css  js  c++  java
  • hdu 1043 八数码--打表

    http://acm.hdu.edu.cn/showproblem.php?pid=1043

    题意:略;

    思路:其实怎么看也是打表的思路比较容易想一些,不过A*搜索真是神奇。。。而且打表快不少,可能和多组数据有关,其实A*也可以记忆化一下应付一下多组数据,大概也会快不少吧。。。

    思路很简单,从最终状态反向暴力BFS就可以了。。因为所有状态也已9!不是很多,主要用hash来去重就可以了。思维含量比A*简单。。

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int dis[12] = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};
    int tmp[10];
    char s[10];
    const int maxn=1e5*4;
    int arr[10];
    int vis[maxn];
    int last[maxn+10];
    int how[maxn+10];
    int ans=-1;
    
    int Cantor(int x, int len){
        int c=0;
        while(x){
            tmp[c++]=x%10;
            x/=10;
        }
        int resl = 1;
        for(int i = 0; i < len; i++){
            int counts = 0;
            for(int k = i + 1; k < len; k++){
                if(tmp[i] > tmp[k]){
                    counts++;
                }
            }
            resl = resl + dis[len-i-1] * counts;
        }
        return resl;
    }
    
    
    
    int tran(int x,int h){
        int c=0,ret=0,idx=0;;
        while(x){
            tmp[c++]=x%10;
            if(tmp[c-1]==9) idx=c-1;
            x/=10;
        }
        if(h==0){
            if(idx<3) return -1;
            else swap(tmp[idx],tmp[idx-3]);
        }
        else if(h==1){
            if(idx%3==2) return -1;
            else swap(tmp[idx],tmp[idx+1]);
        }
        else if(h==2){
            if(idx>5) return -1;
            else swap(tmp[idx],tmp[idx+3]);
        }
        else if(h==3){
            if(idx%3==0) return -1;
            else swap(tmp[idx],tmp[idx-1]);
        }
        for(int i=0,j=1;i<9;i++,j*=10) ret+=tmp[i]*j;
        return ret;
    }
    
    struct node{
        int num,id;
        node(){};
        node(int b,int c):num(b),id(c){};
    };
    
    bool Astar(){
        memset(vis,-1,sizeof(vis));
        memset(last,-1,sizeof(last));
        queue<node> P;
        int x=0,cnt=0;
        for(int i=0,j=1;i<9;i++,j*=10) x+=arr[i]*j;
        P.push(node(x,cnt++));
        vis[Cantor(x,9)]=1;
        while(!P.empty()){
            node t=P.front();
            P.pop();
            ans=t.id;
            for(int i=0;i<4;i++){
                int x=tran(t.num,i);
                if(x!=-1&&vis[Cantor(x,9)]==-1){
                    vis[Cantor(x,9)]=cnt;
                    last[cnt]=t.id;
                    how[cnt]=i;
                    P.push(node(x,cnt++));
                }
            }
        }
        return false;
    }
    
    char re[maxn];
    
    void pr(int x){
        int c=0;
        while(x!=0){
            if(how[x]==0) re[c++]='d';
            else if(how[x]==1) re[c++]='l';
            else if(how[x]==2) re[c++]='u';
            else if(how[x]==3) re[c++]='r';
            x=last[x];
        }
        for(int i=0;i<c;i++) printf("%c",re[i]);
        puts("");
    }
    
    int main(){
        for(int i=0;i<9;i++) arr[i]=i+1;
        Astar();
        while(cin>>s[0]>>s[1]>>s[2]>>s[3]>>s[4]>>s[5]>>s[6]>>s[7]>>s[8]){
            for(int i=0;i<9;i++){
                if(s[i]=='x') arr[i]=9;
                else arr[i]=(int)(s[i]-'0');
            }
            int ret=0;
            for(int i=0,j=1;i<9;i++,j*=10) ret+=arr[i]*j;
            if(ret==987654321) puts("");
            else if(vis[Cantor(ret,9)]!=-1){
                pr(vis[Cantor(ret,9)]);
            }
            else{
                puts("unsolvable");
            }
        }
        return 0;
    }
    



  • 相关阅读:
    Android 中的code sign
    iOS 中的Certificate,Provisioning Profile 的一些注意 (不断完善中)
    xcode 和 android studio中在Mac系统下的自动对齐快捷键
    iOS block 声明时和定义时的不同格式
    iOS 和 Android 中的后台运行问题
    Android 阅读Tasks and Back Stack文章后的重点摘抄
    Android 中PendingIntent---附带解决AlarmManager重复加入问题
    Android 中获得notification的发出时间
    iOS 关于Layer的疑问
    iOS的 context 和Android 中的 canvas
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672535.html
Copyright © 2011-2022 走看看