zoukankan      html  css  js  c++  java
  • POJ 3690 Constellations

    gate

    用时:60min,几乎全是照题解写的,所以没什么bug

    题目大意:
    给定一个(N imes M)的天空,(T)(P*Q)的星座,求有几个星座在天空中出现。
    星空由 (' * ')(' 0 ') 组成。
    多组数据,(1 le N, M le 1000, 1 le T le 100, 1 le P, Q le 50)

    二维哈希

    把每一行、每一列当做一个字符串,用两个不同的模数分别哈希。
    在枚举天空((N imes M))矩阵时,用滚动哈希消去(P imes Q)范围以外的字符的影响

    (s[i][j])表示天空或星座的第(i)行第(j)列的字符。

    先处理横向(先枚举(i),再枚举(j)):
    (g[i][j] = g[i][j-1]*Base1 + s[i][j] (jin[1,Q])\ g[i][j] = g[i][j-1]*Base1 + s[i][j] - s[i][j-Q]*(Base1)^Q (jin[Q+1,M]))

    再处理竖向(先枚举(j),再枚举(i)):
    (j)可以从(Q)开始枚举,因为只有大小为(P*Q)的矩阵是有用的。
    (f[i][j] = f[i-1][j]*Base2 + g[i][j] (iin[i,P])\ f[i][j] = f[i-1][j]*Base2 + g[i][j] - g[i-P][j]*(Base2)^P (iin[P+1,N]))

    处理出每个(P imes Q)矩阵的哈希值后,
    将每个星座的矩阵插入(multiset),再减去每个天空的矩阵。
    最后(T-mset.size())即为答案。

    注意:

    定义函数void cal(char s[][maxn])的时候,如果写成char s[][]
    就会出现declaration of 's' as multidimensional array must have bounds for all dimensions except the first
    这是因为,IDE只允许数组的第一维未给定。
    所以在定义表示星座的变量char b的时候,
    尽管根据范围只需要b[100][50][50],但为了传入cal函数,还是要写成b[100][50][maxn]

    (code)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<set>
    #define MogeKo qwq
    using namespace std;
    
    #define ull unsigned long long
    
    const int maxn = 1005;
    const ull B1 = 19260817;
    const ull B2 = 20031101;
    
    char a[maxn][maxn],b[105][55][maxn]; //55
    
    int n,m,t,p,q,ans;
    ull f[maxn][maxn],g[maxn][maxn];
    ull base1[maxn],base2[maxn];
    
    void init(){
        base1[0] = base2[0] = 1;
        for(int i = 1;i <= 1000;i++){
            base1[i] = base1[i-1] * B1;
            base2[i] = base2[i-1] * B2;
        }
    }
    
    void cal(char s[][maxn],int n,int m){
        for(int i = 0;i < n;i++){
            g[i][0] = s[i][0];
            for(int j = 1;j < q;j++)
                g[i][j] = g[i][j-1]*B1 + s[i][j];
            for(int j = q;j < m;j++)
                g[i][j] = g[i][j-1]*B1 + s[i][j] - s[i][j-q]*base1[q];
        }
        for(int j = 0;j < m;j++){ //j = q-1
            f[0][j] = g[0][j];
            for(int i = 1;i < p;i++)
                f[i][j] = f[i-1][j]*B2 + g[i][j];
            for(int i = p;i < n;i++)
                f[i][j] = f[i-1][j]*B2 + g[i][j] - g[i-p][j]*base2[p];
        }       
    }
    
    void solve(){
        ans = 0;
        multiset <ull> star;
        for(int i = 1;i <= t;i++){
            cal(b[i],p,q);
            star.insert(f[p-1][q-1]);
        }
        cal(a,n,m);
        for(int i = p-1;i < n;i++)
            for(int j = q-1;j < m;j++)
                star.erase(f[i][j]);
        ans = t-star.size();
    }
    
    
    int main(){
        init();
        for(int id = 1;;id++){
            scanf("%d%d%d%d%d",&n,&m,&t,&p,&q);
            if(!(n|m|t|p|q)) break;
            for(int i = 0;i < n;i++)
                scanf("%s",a[i]);
            for(int i = 1;i <= t;i++)
                for(int j = 0;j < p;j++)
                    scanf("%s",b[i][j]);
            solve();
            printf("Case %d: %d
    ",id,ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Elasticsearch轻量搜索与分析
    Elasticsearch文档详解
    Elasticsearch基本概念
    Elasticsearch集群健康
    Elasticsearch搜索与分析
    Redis 面试题 记录
    Redis集群 详解
    从根上理解高性能、高并发(六):通俗易懂,高性能服务器到底是如何实现的
    昔日移动端IM明星 “米聊” 即将停止服务
    从根上理解高性能、高并发(五):深入操作系统,理解高并发中的协程
  • 原文地址:https://www.cnblogs.com/mogeko/p/13278517.html
Copyright © 2011-2022 走看看