zoukankan      html  css  js  c++  java
  • Aizu 0121 Seven Puzzle(变进制数的完美hash)

    一遍预处理跑完所有情况,O(1)回答就好。状态记录我用的康拓和逆康拓。

    #include<bits/stdc++.h>
    using namespace std;
    
    int d[40320];
    int fac[8];
    int u[8];
    
    int cantor()
    {
        int re = 0;
        for(int i = 0; i < 8; i++){
            int inv = 0;
            for(int j = i; ++j < 8; ){
                if(u[i]>u[j]) inv++;
            }
            re += fac[7-i]*inv;
        }
        return re;
    }
    
    void invCantor(int x)
    {
        bool vis[8] = {};
        for(int i = 0; i < 8; i++){
            int w = x/fac[7-i];
            x %= fac[7-i];
            int j = 0;
            for( ; j < 8; j++){
                if(!vis[j]){
                    if(!w) break;
                    w--;
                }
            }
            u[i] = j; vis[j] = true;
        }
    }
    
    int cur;
    queue<int> q;
    
    inline void updata(int p0,int p1)
    {
        swap(u[p0],u[p1]);
        int s = cantor();
        if(!d[s]){
            d[s] = d[cur]+1;
            q.push(s);
        }
        swap(u[p0],u[p1]);
    }
    
    void bfs()
    {
        d[0] = 1;
        q.push(0);
        while(q.size()){
            invCantor(cur = q.front()); q.pop();
            int p;
            for(int i = 0; i < 8; i++)
                if(!u[i]){ p = i; break; }
            int r = p%4;
            if(r) {
                updata(p-1,p);
            }
            if(r<3){
                updata(p+1,p);
            }
            updata(p,p+(p>3?-4:4));
        }
    }
    
    void preDeal()
    {
        fac[0] = 1;
        for(int i = 1; i < 8; i++){
            fac[i] = fac[i-1]*i;
        }
        bfs();
    }
    
    int read()
    {
        if(scanf("%d",u)<0) return -1;
        for(int i = 1; i < 8; i++) scanf("%d",u+i);
        return cantor();
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        preDeal();
        int s;
        while( ~(s = read()) ){
            printf("%d
    ",d[s]-1);
        }
        return 0;
    }
  • 相关阅读:
    poj 1961 Period
    call 大佬 help7——kmp 补齐 循环节
    hdu 3746 Cyclic Nacklace
    poj 2406 Power Strings
    [Baltic2009]Radio Transmission
    poj 2752 Seek the Name, Seek the Fame
    hdu 3336 Count the string
    hdu 2594 Simpsons’ Hidden Talents
    hdu 1711 Number Sequence
    我在开发第一个Swift App过程中学到的四件事
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4889617.html
Copyright © 2011-2022 走看看