UVA12338.Anti-Rhyme Pairs(hash+二分)

题目链接:https://vjudge.net/contest/362376#problem/E在这里插入图片描述在这里插入图片描述
题意:给定几个字符串,找最大前缀长度
解题思路:
利用hash来表示字符串,hash[i]=hash[i-1]*p+s[i]-‘a’+1;
其中p设置得比26大,这样可以保证如果hash1[i]>hash2[i]时,i之后永远都不会存在hash1[i]=hash2[i]
因为这一题多次询问,直接for一个个查询肯定会超时。所以使用二分的方法,如果hash1[mid]=hash2[mid],则l=mid+1,否则r=mid-1;
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<vector>
using namespace std;
#define ll unsigned long long
const int p=131;
vector<ll> Hash[110000];
int n;
int q;
int x,y;
char str[110000];
int df()
{
	int len1=Hash[x].size()-1;
	int len2=Hash[y].size()-1;
	int r=min(len1,len2);
	int l=0;
	int ans=0;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(Hash[x][mid]==Hash[y][mid])
			l=mid+1,ans=max(mid,ans);
		else
			r=mid-1;
	}
	return ans;
}
int main()
{
	int t;
	int f=0;
	cin>>t;
	while(t--)
	{
		cout<<"Case "<<++f<<":"<<endl;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%s",str+1);
			int len=strlen(str+1);
			Hash[i].push_back(0);
			for(int j=1;j<=len;j++)
			{
				Hash[i].push_back(Hash[i][j-1]*p+str[j]-'a'+1);
			}
		}
		scanf("%d",&q);
		for(int i=0;i<q;i++)
		{
			scanf("%d%d",&x,&y);
			x=x-1;
			y=y-1;
			int pos=df();
			cout<<pos<<endl;
		}
		if(t!=0)
			for(int i=0;i<n;i++)
				Hash[i].clear();
	}
	return 0;
}
原创文章 65 获赞 3 访问量 2104

猜你喜欢

转载自blog.csdn.net/littlegoldgold/article/details/104966413