Aizu 1370 Hidden Anagrams 字符串哈希

Hidden Anagrams

Time Limit : 10 sec, Memory Limit : 262144 KB

Problem D Hidden Anagrams

An anagram is a word or a phrase that is formed by rearranging the letters of another. For instance, by rearranging the letters of "William Shakespeare," we can have its anagrams "I am a weakish speller," "I'll make a wise phrase," and so on. Note that when  A A is an anagram of  B B B B is an anagram of  A A.

In the above examples, differences in letter cases are ignored, and word spaces and punctuation symbols are freely inserted and/or removed. These rules are common but not applied here; only exact matching of the letters is considered.

For two strings  s1 s1 and  s2 s2 of letters, if a substring  s1 s1′ of  s1 s1 is an anagram of a substring  s2 s2′ of  s2 s2, we call  s1 s1′hidden anagram of the two strings,  s1 s1 and  s2 s2. Of course,  s2 s2′ is also a hidden anagram of them.

Your task is to write a program that, for given two strings, computes the length of the longest hidden anagrams of them.

Suppose, for instance, that "anagram" and "grandmother" are given. Their substrings "nagr" and "gran" are hidden anagrams since by moving letters you can have one from the other. They are the longest since any substrings of "grandmother" of lengths five or more must contain "d" or "o" that "anagram" does not. In this case, therefore, the length of the longest hidden anagrams is four. Note that a substring must be a sequence of letters occurring consecutively in the original string and so "nagrm" and "granm" are not hidden anagrams.

Input

The input consists of a single test case in two lines.

s1 s1
s2 s2

s1 s1 and  s2 s2 are strings consisting of lowercase letters (a through z) and their lengths are between 1 and 4000, inclusive.

Output

Output the length of the longest hidden anagrams of  s1 s1 and  s2 s2. If there are no hidden anagrams, print a zero.

Sample Input 1

anagram
grandmother

Sample Output 1

4

Sample Input 2

williamshakespeare
iamaweakishspeller

Sample Output 2

18

Sample Input 3

aaaaaaaabbbbbbbb
xxxxxabababxxxxxabab

Sample Output 3

6

Sample Input 4

abababacdcdcd
efefefghghghghgh

Sample Output 4

0


给两个长度最多4000的字符串,判断它们的所有子串中,每个字母出现次数相同的子串的最大长度。

从刘大爷那里学到了一个奇技淫巧,同时也十分玄学的算法:字符串哈希。

对于这题,统计子串中每个字母出现的次数,算出哈希函数之后用map判重即可。


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <bitset>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef unsigned long long ull;
typedef long double ld;
const int maxn=5005,inf=0x3f3f3f3f;
char s[maxn],t[maxn];
int a[26];

ull seed1=26,seed2=1e9+7;

ull hash() {
	ull sum=seed1;
	for (int i=0;i<26;i++) {
		sum*=seed2;
		sum+=a[i];
	}
	return sum;
}

int main() {
	map<ull,int> HashTable;
	scanf("%s",s);
	scanf("%s",t);
	int lena,lenb,i,j,k,ans;
	lena=strlen(s),lenb=strlen(t);
	int len=min(lena,lenb);
	ans=0;
	for (i=1;i<=len;i++) {
		HashTable.clear();
		mem0(a);
		for (j=0;j<i;j++) a[s[j]-'a']++;
		for (j=0;j<lena-i;j++) {
			HashTable[hash()]++;
			a[s[j]-'a']--;
			a[s[j+i]-'a']++;
		}
	//	cout << hash() << endl;
		HashTable[hash()]++;
		mem0(a);
		for (j=0;j<i;j++) a[t[j]-'a']++;
		for (j=0;j<lenb-i;j++) {
	//		cout << hash() << endl;
			if (HashTable[hash()]) ans=max(ans,i);
			a[t[j]-'a']--;
			a[t[j+i]-'a']++;
		}
		if (HashTable[hash()]) ans=max(ans,i);
	}
	printf("%d\n",ans);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值