题目描述:
蒜头君有很多组字符串形如 {x,y}x,y, xx 的长度不确定,而 yy 的长度是 22。
如果有两组字符串 a , ba,b,例如 a =a= {“ABCD”,“CC”} 和 b =b= {“CCAAAA”,“AB”} ,aa 组的第二个字符串是 bb 组第一个字符串的开头,而 bb 组的第二个字符串是 aa 组第一个字符串的开头。这是一个非常有趣的现象,蒜头君会认为这两组字符串 a,ba,b 存在一种特殊关系。
但是蒜头君又觉得例如 a =a= {“ABAB”,“AB”}, b =b= {“ABAC”,“AB”} 这样两组字符串是没有特殊关系的,因为它们的第二个字符串相同。
现在蒜头君有 NN 组字符串,他想要知道这些字符串中有多少组存在特殊关系。
输入格式
第一行输入一个整数 NN,表示有 NN 组字符串;
接下来 NN 行,每行输入两个字符串 x,yx,y(均为大写字母)。
注意:有可能有多个城市叫一样的名字,但是它们肯定不属于同一个省。
注意可能存在相同的 xx 字符串,但保证对于相同的 xx 所对应的字符串 yy 一定不同
输出格式
输出这些字符串中有多少组存在特殊关系。
数据范围
对于 100% 的数据,1≤N≤200000,2≤∣x∣,∣y∣≤10,输入保证所有字符串都由大写字母构成
样例输入
5
JISUANKE SU
SUANKE JI
JISUAN SU
JISK SK
SKSK SK
样例输出
2
在练习的时候卡了很久,脑子不好使不知道怎么用map来存储。本题y固定为2,可以直接采用4位26进制的hash,直接将字符串a的前两位与字符串b连接起来,然后hash维护两个数组,一个数组h1表示原来的数,另一个数组h2用来表示翻转后的数,将两者的乘积相加,最后除以2输出即为答案。
#include<iostream>
#include<cstring>
#include<map>
#include<cstdio>
using namespace std;
#define mp make_pair
const int maxn=2e5+5;
int n;
int h1[26*26*26*27], h2[26*26*26*27];
char s1[20],s2[20];
int main()
{
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%s %s",s1,s2);
if(s1[0] != s2[0] || s1[1] != s2[1]){
int x1 = (((s1[0] - 'A') * 26 + s1[1] - 'A') * 26 + (s2[0] - 'A')) * 26 + s2[1] - 'A';
int x2 = (((s2[0] - 'A') * 26 + s2[1] - 'A') * 26 + (s1[0] - 'A')) * 26 + s1[1] - 'A';
h1[x1]++;
h2[x2]++;
}
}
long long ans = 0;
for(int i = 0; i < 26 * 26 * 26 * 27; i++){
ans += h1[i] * h2[i];
}
cout << ans / 2 << endl;
return 0;
}
本文介绍了一种通过哈希方法解决字符串匹配问题的算法。针对特定格式的字符串组,利用26进制哈希实现快速查找具有特殊关系的字符串组,并提供了一个C++示例程序。
3078

被折叠的 条评论
为什么被折叠?



