zoukankan      html  css  js  c++  java
  • B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash

    一开始以为是dp,后来看了一下标签。。。二分答案?之前也想过,但是没往下想,然后之后的算法就顺理成章,先求出第一个地图的所有子矩阵的hash值,然后求第二个,在上一个地图例二分查找,然后就没了。

    算法很好想,也很好写,但是一开始我想的和最长公共子序列差不多的dp却不行(子矩阵是子串啊)。。。总的来说不是什么难题。

    lower_bound是大于等于,返回的时候不用减一。

    upper_bound是大于。

    题干:

    Description
    Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏。她正在设法寻找更多的战役地图以进一步提高自己的水平。 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打法能够通过的战役地图,她只需要玩一张,她就能了解这一类战役的打法,然后她就没有兴趣再玩儿这一类地图了。而网上流传的地图有很多都是属于同一种打法,因此Blue Mary需要你写一个程序,来帮助她判断哪些地图是属于同一类的。 具体来说,Blue Mary已经将战役地图编码为n*n的矩阵,矩阵的每个格子里面是一个32位(有符号)正整数。对于两个矩阵,他们的相似程度定义为他们的最大公共正方形矩阵的边长。两个矩阵的相似程度越大,这两张战役地图就越有可能是属于同一类的。
    Input
    第一行包含一个正整数n。 以下n行,每行包含n个正整数,表示第一张战役地图的代表矩阵。 再以下n行,每行包含n个正整数,表示第二张战役地图的代表矩阵。
    Output
    仅包含一行。这一行仅有一个正整数,表示这两个矩阵的相似程度。
    Sample Input
    3
    1 2 3
    4 5 6
    7 8 9
    5 6 7
    8 9 1
    2 3 4
    Sample Output
    2
    HINT
    样例解释:
    子矩阵:
    5 6
    8 9
    为两个地图的最大公共矩阵
    
    约定:
    n<=50
    Source

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int n,len = 0;
    ull mp[55][55],mp2[55][55],w[50000];
    bool cmp(ull a,ull b)
    {
        return a < b;
    }
    void haxi(int x,int y,int l)
    {
        ull tot = 0;
        duke(i,x,x + l - 1)
        {
            duke(j,y,y + l - 1)
            {
                tot = tot * 127 + mp[i][j];
            }
        }
        w[++len] = tot;
    }
    ull haxi2(int x,int y,int l)
    {
        ull tot = 0;
        duke(i,x,x + l - 1)
        {
            duke(j,y,y + l - 1)
            {
                tot = tot * 127 + mp2[i][j];
            }
        }
        return tot;
    }
    int main()
    {
        read(n);
        duke(i,1,n)
        duke(j,1,n)
        read(mp[i][j]);
        duke(i,1,n)
        duke(j,1,n)
        read(mp2[i][j]);
        int l = 1,r = n;
        while(l != r)
        {
            clean(w);
            len = 0;
            int mid = (l + r) >> 1;
            duke(i,1,n - mid + 1)
            {
                duke(j,1,n - mid + 1)
                {
                    haxi(i,j,mid);
                }
            }
            sort(w + 1,w + len + 1,cmp);
            int ok = 0;
            duke(i,1,n - mid + 1)
            {
                duke(j,1,n - mid + 1)
                {
                    ull p = haxi2(i,j,mid);
                    int y = lower_bound(w + 1,w + len + 1,p) - w;
                    if(w[y] == p)
                    {
                        ok = 1;
                        break;
                    }
                }
                if(ok == 1)
                    break;
            }
            if(ok == 1)
                l = mid + 1;
            else
                r = mid;
        }
        clean(w);
        len = 0;
        duke(i,1,n - l + 1)
        {
            duke(j,1,n - l + 1)
            {
                haxi(i,j,l);
            }
        }
        sort(w + 1,w + len + 1,cmp);
        int ok = 0;
        duke(i,1,n - l + 1)
        {
            duke(j,1,n - l + 1)
            {
                ull p = haxi2(i,j,l);
                int y = lower_bound(w + 1,w + len + 1,p) - w;
                if(w[y] == p)
                {
                    ok = 1;
                    break;
                }
            }
            if(ok == 1)
                break;
        }
        if(ok == 1)
        write(r);
        else
        write(r - 1);
        return 0;
    }
    /*
    3
    1 2 3
    4 5 6
    7 8 9
    5 6 7
    8 9 1
    2 3 4
    */
    /*
    5
    1 2 3 4 5
    5 6 7 8 9
    8 9 10 11 12
    1 2 3 4 5
    5 4 3 2 1
    1 2 3 5 7
    5 3 1 2 3
    1 4 5 6 7
    4 5 8 9 10
    4 7 1 5 6
    */
  • 相关阅读:
    HDU 2544 最短路
    HDU 3367 Pseudoforest
    USACO 2001 OPEN
    HDU 3371 Connect the Cities
    HDU 1301 Jungle Roads
    HDU 1879 继续畅通工程
    HDU 1233 还是畅通工程
    HDU 1162 Eddy's picture
    HDU 5745 La Vie en rose
    HDU 5744 Keep On Movin
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9538555.html
Copyright © 2011-2022 走看看