zoukankan      html  css  js  c++  java
  • Luogu P4503 [CTSC2014]企鹅QQ(字符串哈希)

    P4503 [CTSC2014]企鹅QQ

    题面

    题目背景

    (PenguinQQ) 是中国最大、最具影响力的 (SNS(Social Networking Services)) 网站,以实名制为基础,为用户提供日志、群、即时通讯、相册、集市等丰富强大的互联网功能体验,满足用户对社交、资讯、娱乐、交易等多方面的需求。

    题目描述

    (Q)(PenguinQQ) 网站的管理员,他最近在进行一项有趣的研究——哪些账户是同一个人注册的。经过长时间的分析,小 (Q) 发现同一个人注册的账户名称总是很相似的,例如 (Penguin1, Penguin2, Penguin3……) 于是小 (Q) 决定先对这种相似的情形进行统计。

    (Q) 定义,若两个账户名称是相似的,当且仅当这两个字符串等长且恰好只有一位不同。例如 (“Penguin1”)(“Penguin2”) 是相似的,但 (“Penguin1”)(“2Penguin”) 不是相似的。而小 (Q) 想知道,在给定的 (n) 个账户名称中,有多少对是相似的。

    为了简化你的工作,小 (Q) 给你的 (N) 个字符串长度均等于 (L) ,且只包含大小写字母、数字、下划线以及 ('@')(64) 种字符,而且不存在两个相同的账户名称。

    输入输出格式

    输入格式:

    第一行包含三个正整数 (N, L, S) 。其中 (N) 表示账户名称数量, (L) 表示账户名称长度, (S) 用来表示字符集规模大小,它的值只可能为 (2)(64)

    (S) 等于 (2) ,账户名称中只包含字符 (‘0’)(‘1’)(2) 种字符;

    (S) 等于 (64) ,账户名称中可能包含大小写字母、数字、下划线以及 ('@')(64) 种字符。

    随后 (N) 行,每行一个长度为 (L) 的字符串,用来描述一个账户名称。数据保证 (N) 个字符串是两两不同的。

    输出格式:

    仅一行一个正整数,表示共有多少对相似的账户名称。

    输入输出样例

    输入样例:

    4 3 64
    Fax
    fax
    max
    mac
    

    输出样例:

    4
    

    说明

    (4) 对相似的字符串分别为: (Fax)(fax)(Fax)(max)(fax)(max)(max)(mac)

    测试点编号 N L S
    1 50 10 64
    2 500 100 64
    3 3000 100 2
    4 3000 100 64
    5 30000 50 2
    6 30000 50 64
    7 30000 200 2
    8 30000 200 64
    9 30000 200 2
    10 30000 200 64

    思路

    (Hash) 是真的强,比 (kmp) 好玩多了。 --Uranus
    那肯定啦。 --alecli

    这是一道字符串哈希的题。考虑如果题目问的不是“相似字符串”而是“相同字符串”,那么可以直接用字符串哈希来解决这一问题。而既然所有字符串的长度相同,考虑枚举相似字符串的不同位,把它去掉,然后比较剩下的字符串是否相同就好了。

    利用字符串哈希的话,只需要求一遍所有字符串前缀的哈希值,再反着跑一遍,求后缀的哈希值,每次合并前缀和后缀就好了。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ULL;
    const ULL Pa=131;
    const ULL Pb=137;
    ULL n,l,s,ans,aHash[30005][205],bHash[30005][205],tmp[30005];
    string str;
    int main()
    {
        cin>>n>>l>>s;
        for(ULL i=0;i<n;i++)
        {
            cin>>str;
            str='0'+str;
            for(ULL j=1;j<=l;j++) aHash[i][j]=aHash[i][j-1]*Pa+str[j];
            for(ULL j=l;j;j--) bHash[i][j]=bHash[i][j+1]*Pb+str[j];
        }
        for(ULL i=1;i<=l;i++)
        {
            for(ULL j=0;j<n;j++) tmp[j]=aHash[j][i-1]*139+bHash[j][i+1]*149;
            sort(tmp,tmp+n);
            int now=0;
            for(ULL j=0;j<n-1;j++)
                if(tmp[j]==tmp[j+1]) ans+=(++now);
                else now=0;
        }
        cout<<ans;
        return 0;
    }
    
    
  • 相关阅读:
    新思路:Exception Handle
    转战github了
    矩阵内积和Schur补
    原子范数及线谱估计
    次梯度方法
    机器学习——推荐系统
    机器学习——异常值检测
    机器学习——聚类分析和主成分分析
    常用不等式集锦
    机器学习——支持向量机(SVM)
  • 原文地址:https://www.cnblogs.com/coder-Uranus/p/9723601.html
Copyright © 2011-2022 走看看