zoukankan      html  css  js  c++  java
  • HDU 2259 Continuous Same Game (2)

    HDU_2259

        做这个题目首先要做Continuous Same Game(1),要不然不好测试对矩阵的操作是否是对的。

        这个题目一开始怎么写怎么超时,如果改成用优先级队列的话就会爆空间,今天早晨才突然发现原来是对下面的这句话理解错了。

        Then I will calculate the average of (Ai/Bi), 1<=i<=100. You will get WA if your ouput is invalid or this average is less than 1.5.

        题目的意思是算100组case的Ai/Bi的平均值,并要求其不小于1.5,而我一开始理解成了每组case都要不小于1.5,这样很可能有些case本来就不存在比贪心策略更好的解法,从而导致了死循环。

        因此这个题目可以随便搞个靠谱一点的贪心策略,然后用优先级队列搜几十步(具体多少步就要看实际情况了,如果MLE了就把步数改少点,如果WA了就把步数改大点)并取pop出的结果中的最优值输出即可。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #define MAXN 20
    #define MAXD 210
    #define MAXL 30
    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    int N, M, a[MAXN][MAXN];
    void init()
    {
        int i, j;
        char b[MAXN];
        for(i = N - 1; i >= 0; i --)
        {
            scanf("%s", b);
            for(j = 0; j < M; j ++) a[i][j] = b[j] - '0';
        }
    }
    struct List
    {
        int x, y;    
    };
    struct St
    {
        int N, M, c, g[MAXN][MAXN], cnt[MAXD], col[MAXN][MAXN], A, L;
        int value;
        List list[MAXL];
        bool operator < (const St &t) const
        {
            return value < t.value;    
        }
        void init(int N, int M, int g[][MAXN])
        {
            A = value = L = 0;
            this->N = N, this->M = M;
            memcpy(this->g, g, sizeof(this->g));
        }
        inline int inside(int x, int y)
        {
            return x >= 0 && x < N && y >= 0 && y < M;
        }
        void color(int x, int y, int &cnt, int c)
        {
            int i, nx, ny;
            col[x][y] = c, ++ cnt;
            for(i = 0; i < 4; i ++)
                {
                nx = x + dx[i], ny = y + dy[i];
                   if(inside(nx, ny) && g[nx][ny] == g[x][y] && !col[nx][ny])
                    color(nx, ny, cnt, c);
                }
        }
        void erase(int x, int y)
        {
            int i, nx, ny;
            g[x][y] = 0;
                for(i = 0; i < 4; i ++)
            {
                nx = x + dx[i], ny = y + dy[i];
                if(inside(nx, ny) && col[x][y] == col[nx][ny] && g[nx][ny])
                    erase(nx, ny);
            }
        }
        inline int find(int j)
        {
            for(int i = 0; i < N; i ++) if(g[i][j]) return 0;
            return 1;
        }
        void arrange()
        {
               int i, j, k, kmax;
               kmax = 0;
            for(j = 0; j < M; j ++)
            {
                k = 0;
                for(i = 0; i < N; i ++)
                    if(g[i][j])
                    {
                        if(i != k)
                            g[k][j] = g[i][j], g[i][j] = 0;
                        ++ k;
                    }
                kmax = std::max(kmax, k);
            }
            N = kmax;
            k = 0;
            for(j = 0; j < M; j ++)
                if(!find(j))
                {
                    if(j != k) for(i = 0; i < N; i ++) g[i][k] = g[i][j];
                    ++ k;
                }
            M = k;
        }
        void deal()
        {
            int i, j;
            c = 0;
            for(i = 0; i < N; i ++)
                for(j = 0; j < M; j ++) col[i][j] = 0;
            for(i = N - 1; i >= 0; i --)
                for(j = 0; j < M; j ++)
                    if(g[i][j] && !col[i][j])
                       {
                        ++ c, cnt[c] = 0;
                        color(i, j, cnt[c], c);
                        if(cnt[c] == 1) col[i][j] = 0, -- c;
                    }
        }
        void cal()
        {    
            value = A;
            for(int i = 1; i <= c; i ++) if(cnt[i]) value += cnt[i] * (cnt[i] - 1);
        }
    };
    void solve()
    {
        int i, j, cnt = 0, max, x, y;
        St ans;
        ans.init(N, M, a);
        ans.deal(), ans.cal();
        std::priority_queue <St> q;
        q.push(ans);
        while(!q.empty())
        {
            St st = q.top();
            q.pop();
            if(st.A > ans.A) ans = st;
            if(++ cnt >= 25) break;
            st.deal();
            for(i = 0; i < st.N; i ++)
                for(j = 0; j < st.M; j ++)
                {
                    int c = st.col[i][j];
                    if(c && st.cnt[c] > 1)
                    {
                        St nt = st;
                        nt.erase(i, j), nt.arrange();
                        nt.A += st.cnt[c] * (st.cnt[c] - 1);
                        nt.deal(), nt.cal();
                        nt.list[nt.L].x = i, nt.list[nt.L].y = j, ++ nt.L;
                        q.push(nt);
                    }
                    st.cnt[c] = 0;
                }
        }
        printf("%d\n", ans.L);
        for(i = 0; i < ans.L; i ++)
            printf("%d %d\n", N - ans.list[i].x - 1, ans.list[i].y);
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    would clobber existing tag
    已成功与服务器建立连接,但是在登录前的握手期间发生错误。 (provider: TCP 提供程序, error: 0
    C#搭建简单的http服务器,访问静态资源
    使用iis反向代理
    WorkerServices部署为Windows服务
    mongo 操作数据库的方式
    odoo db_name 指定多个数据库
    odoo 如何设置字段变更跟踪
    odoo qweb 视图使用widget
    odoo 代码片段比较全的扩展
  • 原文地址:https://www.cnblogs.com/staginner/p/2663524.html
Copyright © 2011-2022 走看看