zoukankan      html  css  js  c++  java
  • HDU 2234 无题I

    HDU_2234

        这个题目可以先从终态出发,把5步以内的所有状态预处理出来,同时为了进一步减少状态,利用最小表示法的思想,将终态看成只有两种:

    1111

    2222

    3333

    4444

    1234

    1234

    1234

    1234

    ,这样我的程序最终跑出来就只有157370个状态了。

        在查询的时候,由于前面我们用最小表示法将状态简化了,那么现在就要将1、2、3、4全排列一下生成24种状态,每种状态都查找一下,然后取这24种状态下的最小值。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define HASH 1000007
    #define MAXD 1000010
    #define INF 0x3f3f3f3f
    typedef unsigned int _int;
    struct HashMap
    {
        int head[HASH], size, next[MAXD];
        _int st[MAXD];
        void init()
        {
            memset(head, -1, sizeof(head));
            size = 0;
        }
        int find(_int _st)
        {
            int i, h = _st % HASH;
            for(i = head[h]; i != -1; i = next[i])
                if(st[i] == _st) break;
            return i;    
        }
        void push(_int _st)
        {
            int h = _st % HASH;    
            st[size] = _st;
            next[size] = head[h], head[h] = size ++;
        }
    }hm;
    int trans[][4] =
    {
        {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1},
        {1, 0, 2, 3}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 0, 3, 2}, {1, 3, 0, 2}, {1, 3, 2, 0},
        {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
        {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0},
    };
    _int q[MAXD];
    int  dis[MAXD], code[4][4];
    _int encode(int code[][4])
    {
        int i, j;
        _int ans = 0;
        for(i = 0; i < 4; i ++)
            for(j = 0; j < 4; j ++) ans = ans << 2 | code[i][j];
        return ans;
    }
    void decode(_int st)
    {
        int i, j;
        for(i = 3; i >= 0; i --)
            for(j = 3; j >= 0; j --) code[i][j] = st & 3, st >>= 2;
    }
    void shr(int r, int k)
    {
        int i;
        if(k == 0) for(i = 0; i < 3; i ++) std::swap(code[r][i], code[r][i + 1]);
        else for(i = 3; i >= 1; i --) std::swap(code[r][i], code[r][i - 1]);
    }
    void shc(int c, int k)
    {
        int i;
        if(k == 0) for(i = 0; i < 3; i ++) std::swap(code[i][c], code[i + 1][c]);
        else for(i = 3; i >= 1; i --) std::swap(code[i][c], code[i - 1][c]);    
    }
    void prepare()
    {
        int i, j, k, rear = 0;
        _int x, y;
        hm.init();
        for(i = 0; i < 4; i ++)
            for(j = 0; j < 4; j ++) code[i][j] = i;
        x = encode(code);
        hm.push(x), q[rear ++] = x;
        for(i = 0; i < 4; i ++)
            for(j = 0; j < 4; j ++) code[i][j] = j;
        x = encode(code);
        hm.push(x), dis[rear] = 0, q[rear ++] = x;
        for(i = 0; i < rear; i ++)
        {
            if(dis[i] >= 5) continue;
            x = q[i];
            decode(x);
            for(j = 0; j < 4; j ++)
                for(k = 0; k < 2; k ++)
                {
                    shr(j, k);
                    y = encode(code);
                    if(hm.find(y) == -1)
                        hm.push(y), dis[rear] = dis[i] + 1, q[rear ++] = y;
                    shr(j, k ^ 1);
                    shc(j, k);
                    y = encode(code);
                    if(hm.find(y) == -1)
                        hm.push(y), dis[rear] = dis[i] + 1, q[rear ++] = y;
                    shc(j, k ^ 1);    
                }    
        }
        //printf(">> %d\n", rear);
    }
    void solve()
    {
        int i, j, k, g[4][4], ans = INF;
        for(i = 0; i < 4; i ++)
            for(j = 0; j < 4; j ++) scanf("%d", &g[i][j]), -- g[i][j];
        for(k = 0; k < 24; k ++)
        {
            for(i = 0; i < 4; i ++)
                for(j = 0; j < 4; j ++) code[i][j] = trans[k][g[i][j]];
            i = hm.find(encode(code));
            if(i != -1) ans = std::min(ans, dis[i]);
        }
        if(ans == INF) printf("-1\n");
        else printf("%d\n", ans);
    }
    int main()
    {
        prepare();
        int t;
        scanf("%d", &t);
        while(t --)
            solve();
        return 0;    
    }
  • 相关阅读:
    CF932E Team Work
    BZOJ 4480 [JSOI2013] 快乐的jyy
    CF285E Positions in Permutations
    P4312 [COCI 2009] OTOCI / 极地旅行社
    P3327 [SDOI2015]约数个数和
    P3649 [APIO2014]回文串
    P3181 [HAOI2016]找相同字符
    P3346 [ZJOI2015]诸神眷顾的幻想乡
    P4248 [AHOI2013]差异
    P4512 【模板】多项式除法
  • 原文地址:https://www.cnblogs.com/staginner/p/2660223.html
Copyright © 2011-2022 走看看