zoukankan      html  css  js  c++  java
  • Memento Mori (二维前缀和 + 枚举剪枝)

    枚举指的是枚举矩阵的上下界,然后根据p0, p1, p2的关系去找出另外的中间2个点。然后需要记忆化一些地方防止重复减少时间复杂度。这应该是最关键的一步优化时间,指的就是代码中to数组。然后就是子矩阵的一个计算了,需要用二维前缀和预处理数据,然后判断的时候直接O(1)查询就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int inf  = 0x3f3f3f3f;
    const int maxn = 2e3 + 7;
    struct node{
        int x, y;
        node(){}
        node(int x, int y) : x(x), y(y){}
    }a[maxn], b[maxn], c[maxn], X[4];
    int p[4], matdp[maxn][maxn], to[maxn][2];
    
    bool cmp1(const node &a, const node &b){
        return a.x < b.x;
    }
    bool cmp2(const node &a, const node &b){
        return a.y > b.y;
    }
    bool cmp3(const node &a, const node &b){
        return a.y < b.y;
    }
    
    int howmany(int x1, int y1, int x2, int y2){
        return matdp[x2][y2] + matdp[x1 - 1][y1 - 1] - matdp[x1 - 1][y2] - matdp[x2][y1 - 1];
    }
    bool isOK(){
        int x1 = inf, y1 = inf, x2 = 0, y2 = 0;
        for(int i = 0; i < 4; i ++){
            x1 = min(x1, X[i].x); x2 = max(x2, X[i].x);
            y1 = min(y1, X[i].y); y2 = max(y2, X[i].y);
            for(int j = i + 1; j < 4; j ++)
                if((p[j] - p[i]) * (X[j].y - X[i].y) <= 0) return false;
        }
        return howmany(x1, y1, x2, y2) == 4;
    }
    
    int main(){
        int T, n, m, k, x, y;scanf("%d",&T);
        while(T --){
            scanf("%d%d%d", &n, &m, &k);
            scanf("%d%d%d%d", &p[0], &p[1], &p[2], &p[3]);
            int big = 0, small = 0, ans = 0;
            (p[0] > p[1]) ? small ++ : big ++;
            (p[0] > p[2]) ? small ++ : big ++;
            memset(matdp, 0, sizeof(matdp));
            for(int i = 1; i <= k; i ++){
                scanf("%d%d", &x, &y);matdp[x][y] = 1;
                a[i] = b[i] = c[i] = node(x, y);
            }
            for(int i = 1; i <= n; i ++){
                for(int j = 1; j <= m; j ++)
                    matdp[i][j] += matdp[i][j - 1];
                for(int j = 1; j <= m; j ++)
                    matdp[i][j] += matdp[i - 1][j];
            }
            sort(a + 1, a + k + 1, cmp1);
            sort(b + 1, b + k + 1, cmp2);
            sort(c + 1, c + k + 1, cmp3);
            for(int i = 1; i <= k; i ++){
                X[0] = a[i];
                for(int j = 0; j <= k; j ++)
                    to[j][0] = to[j][1] = j == k ? 0 : j + 1;
                for(int j = k; j > i; j --){
                    if(a[i].x == a[j].x) break;
                    if((p[3] - p[0]) * (a[j].y - a[i].y) <= 0) continue;
                    X[3] = a[j]; X[1] = X[2] = node(-1, -1);
                    int u = 0, v, bi = big, sm = small, t = 1;
                    while(sm --){
                        for(v = u, u = to[u][0]; u; to[v][0] = to[u][0], v = u, u = to[u][0])
                            if(a[i].x < b[u].x && b[u].x < a[j].x && b[u].y < a[i].y){
                                X[t ++] = b[u];break;
                            }
                    }
                    u = 0;
                    while(bi --){
                        for(v = u, u = to[u][1]; u; to[v][1] = to[u][1], v = u, u = to[u][1])
                            if(a[i].x < c[u].x && c[u].x < a[j].x && c[u].y > a[i].y){
                                X[t ++] = c[u];break;
                            }
                    }
                    if(t < 3 || X[1].x == X[2].x) continue;
                    if(X[1].x > X[2].x) swap(X[1], X[2]);
                    if(isOK()) ans ++;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    more crazy more get!
  • 相关阅读:
    Docker 相关资源
    ReferenceFinder 学习
    AssetBundle 复习
    Coroutine 复习
    Unreal 相关资源
    Houdini 相关资源
    MySQL多数据库合并到一个数据库
    Module is not specified
    idea导入多maven项目
    redis-cluster部署遇到为问题记录
  • 原文地址:https://www.cnblogs.com/wethura/p/9788932.html
Copyright © 2011-2022 走看看