CodeForces - 1200E Compress Words(字符串哈希)

题目链接:点击查看

题目大意:给出n个字符串,现在需要将其依次合并,合并的规则是如果相邻两个字符串中的前后缀有相同的,则合并后省略掉后面字符串的前缀,我们需要保证这个相同的前后缀如果存在的情况下必须最大,输出合并后的字符串

题目分析:可以直接哈希暴力然后string类合并,不过由于这是在cf,用哈希的一个弊端就是很容易被hack,我一开始用一直用的base131和ull写了个单哈希,被test65卡住了,去网上搜了一下题解,发现大家基本上都是单哈希被卡住了,不过我找到了一个可以苟过去的数据:base=2333333,mod=999999998,这个可以单哈希苟过去,如果以后再遇到类似的问题,肯定直接三哈希起步了。。如果再被卡就继续加嘛,反正写好了一个哈希之后就可以直接CV大法了

最后感叹一句,没想到哈希还能倒着来,真的是学到了学到了

代码:

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;
 
typedef long long LL;
 
typedef unsigned long long ull;
 
const int inf=0x3f3f3f3f;
 
const int N=1e6+100;
 
const int mod=999999998;
 
const int base=2333333;
 
string s,ans;
 
int main()
{
//	freopen("input.txt","r",stdin);
//	ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	cin>>ans;
	for(int i=2;i<=n;i++)
	{
		cin>>s;
		ull hash1=0,hash2=0,temp=1;
		int mark=0;
		for(int len=1;len<=min(ans.size(),s.size());len++)//枚举长度 
		{
			hash1=(hash1*base+ans[ans.size()-len])%mod;
			hash2=(s[len-1]*temp+hash2)%mod;
			temp=temp*base%mod;
			if(hash1==hash2)
				mark=len;
		}
		ans+=s.substr(mark);
	}
	cout<<ans<<endl;
	
	
	
	
	
	
	
	
	
	
	
	
	return 0;
}
发布了558 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104006155