[CTSC2014] 企鹅QQ
这种东西一看就是字符串hash搞。
先从前往后哈希一遍,再从后往前哈希一遍。
这样我们就可以O(1)提取出去掉某一位的哈希值。
接下来考虑计算相似字符串的数目。
总数=仅在第一位不一样的+仅在第二位不一样的+......+仅在第L位不一样的。
我们先枚举每一位,再把每个字符串去掉这一位的哈希值算出来,看有没有重复的。
判重方法有很多,我用的是排序之后再计算的方法。
有个诡异的地方,算去掉某一位的哈希值tmp的时候,如果两边的哈希值相加之前不分别乘seed,会狂wa不止......
我也不知道为什么。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef unsigned long long ull; 6 7 const int sd[2]={107,127}; 8 int n,l,s; 9 ull mul[205]; 10 ull hs[30005][205][2]; 11 int ans; 12 13 int main() 14 { 15 scanf("%d%d%d",&n,&l,&s); 16 for(int i=1;i<=n;i++) 17 { 18 char str[205]; 19 scanf("%s",str+1); 20 for(int j=1;j<=l;j++) 21 hs[i][j][0]=hs[i][j-1][0]*sd[0]+str[j]-'@'+1; 22 for(int j=l;j;j--) 23 hs[i][j][1]=hs[i][j+1][1]*sd[1]+str[j]-'@'+1; 24 } 25 ull tmp[30005]; 26 for(int i=1;i<=l;i++) 27 { 28 for(int j=1;j<=n;j++) 29 tmp[j]=hs[j][i-1][0]*sd[0]+hs[j][i+1][1]*sd[1]; 30 sort(tmp+1,tmp+n+1); 31 int nw=1; 32 for(int j=2;j<=n;j++) 33 { 34 if(tmp[j]==tmp[j-1])ans+=nw,nw++; 35 else nw=1; 36 } 37 } 38 printf("%d",ans); 39 return 0; 40 }