题解【[CTSC2014]企鹅QQ】

原题链接:Link

前言

sk 邀请做一下这道题目,于是我就来了

思路

一开始之间想到的是暴力枚举,但很明显时间复杂度 O(n^2) 必然TLE,然后与 sk 稍微交流了一下,发现一种 O(nl log n) 的解法。具体就是先求出字符两侧的 Hash 值,然后用 sort 排序记录一下相同的字符串数量。细节不多,但实现还是有难度的。注释在代码里。

代码

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long 
int n,l,m;
int ans;
char s[201];
ull q[30001][201],h[30001][201];
ull tmp[30001];//我开了ull,但是long long就可以了。
int main(){
    cin>>n>>l>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);//注意一下过滤第一次输出,这样处理应该比较简单。
        for(int j=1;j<=l;j++){
            q[i][j]=q[i][j-1]*149+s[j];
        }
        for(int j=l;j>=1;j--){
            h[i][j]=h[i][j+1]*137+s[j];
        }//计算两侧hash。
    }
    for(int i=1;i<=l;i++){
        for(int j=1;j<=n;j++){
            tmp[j]=q[j][i-1]*233+h[j][i+1]*213;//两边hash汇总给tmp数组
        }
        sort(tmp,tmp+n+1);排序
        int f=1;
        for(int j=2;j<=n;j++){
            if(tmp[j]==tmp[j-1]){
                ans+=f;
                f++;
            }
            else{
                f=1;
            }
        }//模拟求出答案
    }
    cout<<ans;
    return 0;
}

具体实现就是这样,有什么不懂还可以私信我。

管理员审核辛苦了

posted @ 2020-03-03 23:33  Kriraya  阅读(134)  评论(0)    收藏  举报