洛谷P4503 [CTSC2014]企鹅QQ

洛谷P4503 [CTSC2014]企鹅QQ

本题在CTSC中算简单的了 但是它仍然是CTSC啊
这题是我的第二道字符串hash,有一定难度
这题的主要难点:

1. 如何判断两个用户名是同一个人

题目中说:若两个账户名称是相似的,当且仅当这两个字符串等长且恰好只有一位不同
而题目中又说:为了简化你的工作,小Q给你的N 个字符串长度均等于L
这一波简直爽歪歪,我们只需要枚举每一个位置,把该字符串减去那一个字符的hash值算出来,然后暴力判断(下面讲)

2.如何计算答案

这个题目的第二个难点在于如何计算答案。由于一些字符串可能会两两相等,我们用一个temp来记录当前有几个字符串相等,当下一个字符串相等时,由于它和前面的都相等,所以ans+=temp

3.新手hash上路提醒
  • 大质数玄学一点听说搞个妹子生日啥的会rp++
  • 字符串 hash时经常会预处理一波pow
  • 字符串 hash时用unsigned long long(自动取模)

代码:

#include<iostream>
#include<algorithm> 
#include<cstdio>
using namespace std;
const int p=31131;
unsigned long long a[30010],pow[210],hash[30010];
int N,L,S,temp,ans;
char s[30010][210];
int main()
{
	scanf("%d%d%d",&N,&L,&S);
	pow[0]=1;
	for (int i=1;i<=210;i++)
		pow[i]=pow[i-1]*p;
	for (int i=1;i<=N;i++)
		scanf("%s",s[i]+1);
	for (int i=1;i<=N;i++){
		for (int j=1;j<=L;j++){
			hash[i]=hash[i]*p+s[i][j];
		}
	}
	for (int k=1;k<=L;k++){
		for (int i=1;i<=N;i++){
			a[i]=hash[i]-pow[L-k]*s[i][k];
		}
		sort(a+1,a+N+1);
		temp=0;
		for (int i=2;i<=N;i++){
			if (a[i]==a[i-1]){
				temp++;
				ans+=temp;
			}
			else temp=0;
		}
	}
	printf("%d",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值