hdu 1043(八数码问题)

题意:省略

 解题思路:针对八数码问题,如果x往左或往右走,是不会改变逆序数大小的,且往上或往下走只有三种情况,讨论往下走,如果与x交换的数是ai,则要判断的是a(i-1),a(i-2)与ai的关系.

                 只会出现四种情况,a(i-1)>ai,a(i-2)>ai;逆序对数在原来的基础上+2

 a(i-1)ai;逆序对数在原来的基础上不变

                                                 a(i-1)>ai,a(i-2)逆序对数在原来的基础上不变

 a(i-1)逆序对数在原来的基础上-2

 针对上述四种情况,逆序数的初始值为0,则经过各种变换逆序数为偶数,则若一种状态逆序数为奇数,始不可能的。且在保存状态时利用康托展开:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! (ai为某个数对应的逆序对数,达到状态压缩)。

 这里要利用反向的思维,通过最终状态去bfs所有状态。          





                 只会出现四种情况,a(i-1)>ai,a(i-2)>ai;逆序对数在原来的基础上+2

 a(i-1)ai;逆序对数在原来的基础上不变

                                                 a(i-1)>ai,a(i-2)

 a(i-1)

 针对上述四种情况,逆序数的初始值为0,则经过各种变换逆序数为偶数,则若一种状态逆序数为奇数,始不可能的。且在保存状态时利用康托展开:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! (ai为某个数对应的逆序对数,达到状态压缩)。

 这里要利用反向的思维,通过最终状态去bfs所有状态。

#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 50
#define MAZE 600000
typedef struct node{
    char str[50];
    int nx[9];
    int num,hashnum,xind;
    node();
    node(char *ss,int nu,int hanu,int *nnx){
        strcpy(str,ss);
        num = nu;
        hashnum = hanu;
        for(int i=0;i<9;++i){
            nx[i] = nnx[i];
        }
    }
    void charstr(){
        int tmp = 0;
        int tmpc;
        int tmpnum = num;
        tmpc = 9;
        int zflag = 0;
        while(num){
            zflag = num%10;
            str[tmpc -1] = '0'+ zflag;
            if(zflag==9)
                tmp = tmpc - 1;
            num/=10;
            --tmpc;
        }
        num = tmpnum;
        xind = tmp;
        //return tmp;
    }
};
queueq;
int path[MAZE];
int nx[9];
int pa[MAZE],ans[MAZE];
bool vis[MAZE];
char nows[MAXN];
int cnt;
int p[]={1,1,2,6,24,120,720,5040,40320};
int pw[] = {100000000,10000000,1000000,100000,10000,1000,100,10,1};
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int goal;
void prepro(){
    cnt = 0;
    int len = (int)strlen(nows);
    for(int i=0;istr[j])tmpc++;
        }
        nx[i] = tmpc;
        ans+=tmpc*p[8-i];
        //st++;
    }
    return ans;
}

int getnx(){
    int ans = 0;
    for(int i=0;inows[j])
                ans++;
        }
    }
    return ans;
}
int getnumber(){
    int   ans = 123456789;
    return ans;
}
//右 左 下 上
int gethash(char *str,int num,int dir,int xind,int nxind,node &no){
    int tmpcc;
    if(dir==0){
        
        num = num-p[8-xind]*no.nx[xind]  - p[8-nxind]*no.nx[nxind];
        tmpcc = no.nx[nxind];
        no.nx[nxind]=no.nx[xind] - 1;
        no.nx[xind] = tmpcc;
        num+=p[8-xind]*no.nx[xind]  + p[8-nxind]*no.nx[nxind];
    }
    if(dir==1){
        num = num-p[8-xind]*no.nx[xind]  - p[8-nxind]*no.nx[nxind];
        tmpcc = no.nx[nxind];
        no.nx[nxind]=no.nx[xind] + 1;
        no.nx[xind] = tmpcc;
        num+=p[8-xind]*no.nx[xind]  + p[8-nxind]*no.nx[nxind];
    }
    
    if(dir==2){
        int ind1,ind2;
        ind1 = xind+1;
        ind2 = xind+2;
        int cc = 0;
        if(str[nxind]>str[ind1])cc++;
        if(str[nxind]>str[ind2])cc++;
        num = num-p[8-xind]*no.nx[xind]  - p[8-nxind]*no.nx[nxind];
        tmpcc = no.nx[nxind];
        no.nx[nxind]=no.nx[xind] - 3;
        no.nx[xind] = tmpcc+cc;
        num+=p[8-xind]*no.nx[xind]  + p[8-nxind]*no.nx[nxind];
        if(str[nxind]str[ind1])cc++;
        if(str[nxind]>str[ind2])cc++;
        num = num-p[8-xind]*no.nx[xind]  - p[8-nxind]*no.nx[nxind];
        tmpcc = no.nx[nxind];
        no.nx[nxind]=no.nx[xind] + 3;
        no.nx[xind] = tmpcc-cc;
        num+=p[8-xind]*no.nx[xind]  + p[8-nxind]*no.nx[nxind];
        if(str[nxind]str[ind1])cc++;
        if(str[nxind]>str[ind2])cc++;
        //        num = num-p[8-xind]*no.nx[xind]  - p[8-nxind]*no.nx[nxind] + p[8-xind]*(no.nx[nxind]-2)  + p[8-nxind]*(no.nx[xind]+cc);
        tmpcc = no.nx[xind];
        no.nx[xind]=no.nx[nxind] + 3;
        no.nx[nxind] = tmpcc-cc;
        if(str[nxind]str[ind1])cc++;
        if(str[nxind]>str[ind2])cc++;
        tmpcc = no.nx[xind];
        no.nx[xind]=no.nx[nxind] - 3;
        no.nx[nxind] = tmpcc+cc;
        if(str[nxind]=0&&nx<3&&ny>=0&&ny<3){
                nxind = nx*3+ny;
                tmpnum = gethash(no.str,no.hashnum,i,xind,nxind,no);
                int cc = no.str[nxind] - '0';
                no.str[xind] = no.str[nxind];
                no.str[nxind] = '9';
                // int chc = charhash(no.str);
                int t1,t2;
                //  t1 = no.num;
                t2 = no.hashnum;
                if(!vis[tmpnum]){
                    pa[tmpnum] = no.hashnum;
                    path[tmpnum] = i;
                    //   int tmpcc = num +  (9 - cc)*(pw[nxind]-pw[xind]);
                    //  no.num = tmpcc;
                    no.hashnum = tmpnum;
                    no.xind = nxind;
                    q.push(no);
                }
                no.str[nxind] = no.str[xind];
                no.str[xind] = '9';
                // no.num = t1;
                no.hashnum = t2;
                no.xind = xind;
                restart(no.str,no.hashnum,i,xind,nxind,no);
            }
        }
    }
    //   return false;
}
int getdir(int num){
    switch(num){
        case 0: return 'l';
        case 1: return 'r';
        case 2: return 'u';
        case 3: return 'd';
    }
    return  0;
}
void output(bool flag,int hashnum){
    if(!flag){
        printf("unsolvable\n");
        return;
    }
    int cntans = 0;
    int tmp = hashnum;
    //char ss[]="ullddrurdllurdruldr";
    //printf("%d\n",strlen(ss));
    while(1){
        if(pa[tmp]==-1)break;
        ans[cntans++] = path[tmp];
        tmp = pa[tmp];
        
    }
    //printf("%d",ans[0]);
    // printf("%d\n",cntans);
    for(int i=0;i


你可能感兴趣的:(hash总结)