HDU Eight

/**
    学长要俄们学下康托~
康托展开式的神奇应用:可以把一组数的全排列一一对应到某个排列的在所有排列的顺序位置上;
      比如{1, 2, 3}有6个全排列, 给出{3, 2, 1}就能计算出是第几个排列, 这样相比直接hash的空间
       就能从333减少到6 , 神奇~
                                                   x的计算结果 = 个数 * (位置 - 1)!
    具体应用:{1, 2, 3}的排列中的{3, 2, 1}, 后面比3小的数有2个, res3 = 2 * 2!
                                          后面比2小的数有1个, res2 = 1 * 1!
                                          后面比1小的数有0个, res1 = 0 * 0!;
                                                                                                                                                                                               resall = 5
                                                      => {3, 2,1}是第六个排列
                                                                           ps:康托还可以逆推出排列

    那么这题, 一个数组就能搞定了~, 9个数max(resall) = (8 * 8! + 7 * 7!.... + 1), 36W而已

*/
bool state[400000];
const int factor[] = {0, 1, 2, 6, 24, 120, 720, 5040, 40320};///预处理(0 - 8)!
int factor1[12][12];
string  ans[400000];

int get_kangtuo(Map st)
{
        int resall = 0;
        Rep(0, 8){
            int minNum = 0;
            for(int j = i + 1; j <=  8; j++){
                if(st.mp[i/3][i%3] > st.mp[j/3][j%3])//第9 - i个位置
                    minNum++;
            }
            resall += factor1[minNum][8 - i];   ///min *(8 - i)!
        }
        return resall;
}
void solve(){
        int i = 0 , j = 0;
        while(true){
            if(ss[j] == 'x'){
                s.mp[i/3][i%3] = 9;
                i++;
            }else if(ss[j]>= '0' && ss[j] <= '9'){
                s.mp[i/3][i%3] = ss[j] - '0';
                i++;
            }
            j++;
            if(i == 9)break;
        }
        int stt = get_kangtuo(s);
        if(state[stt]){
            cout<q;
    q.push(e);
    int mst;
    state[0] = 1;
    while(!q.empty()){
        Map tt = q.front(), tt1; q.pop();
        mst = get_kangtuo(tt);
       // tt.show();
       string opt = tt.op;
       reverse(opt.begin(), opt.end());
        ans[mst] = opt;
        Rep(0, 3){
            int I = tt.y + dir[i][0], J = tt.x + dir[i][1];
            if(I >= 0 && I < 3 && J >= 0 && J < 3){
                tt1 = tt;
                tt1.y = I; tt1.x = J;
                swap(tt1.mp[tt.y][tt.x], tt1.mp[I][J]);
                mst = get_kangtuo(tt1);
                if(!state[mst]){
                    state[mst] = 1;
                    tt1.op = tt1.op + cop[i];
                    q.push(tt1);
                }
            }
        }
    }
}
void makeList(){

    Rep(0, 8){
        for(int j = 0; j <= 8; j++){
            factor1[i][j] = factor[j] * i;
        }
        e.mp[i/3][i%3] = i + 1;
    }
    e.y = 2; e.x = 2;
    bfs();
}
int main(){
  makeList();
   while(gets(ss)){
        solve();
        //cout<


 

你可能感兴趣的:(130414)