题面
大秦为你打开题目传送门
题目描述
两个字符串相似的定义:当且仅当这两个字符串等长且恰好只有一位不同。
例如“Penguin1”和“Penguin2”是相似的,但“Penguin1”和“2Penguin”不是相似的。
给定N个字符串,判断它们有多少对是相似的。
给定的字符串长度均等于L,且只包含大小写字母、数字、下划线以及 ‘@’ 共64种字符,而且不存在两个相同的字符串。
思路
由于每个字符串的长度相当的小,也就说,我们完全可以枚举那个不一样的位,哈希求最长连号时顺便统计即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include<bits/stdc++.h> using namespace std;
typedef unsigned long long ull; const ull P = 131;
int n, L; char s[30010][210];
ull hsh[30010][210]; ull power[210]; ull t[30010];
void Input() { scanf("%d%d", &n, &L); for(int i = 1; i <= n; i++) { scanf("%s", s[i] + 1); for(int j = 1; j <= L; j++) { hsh[i][j] = hsh[i][j - 1] * P + s[i][j]; } } }
void Work() { power[0] = 1; for(int i = 1; i <= L; i++) { power[i] = power[i - 1] * P; } int ans = 0; for(int i = 1; i <= L; i++) { for(int j = 1; j <= n; j++) { t[j] = hsh[j][L] - (hsh[j][i] - hsh[j][i - 1] * P) * power[L - i] - hsh[j][i - 1] * (power[L - i + 1] - power[L - i]); } sort(t + 1, t + n + 1); int tmp = 1; for(int j = 1; j < n; j++) { if(t[j] != t[j + 1]) tmp = 1; else { ans += tmp; tmp++; } } } printf("%d\n", ans); }
int main() { Input(); Work(); return 0; }
|