zoukankan      html  css  js  c++  java
  • [codeforces] 25E Test || hash

    原题

    给你三个字符串,找一个字符串(它的子串含有以上三个字符串),输出此字符串的长度。


    先暴力判断是否有包含,消减需要匹配的串的数量。因为只有三个字符串,所以暴力枚举三个串的位置关系,对三个串跑好哈希,然后判断后缀与前缀重合长度即可。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define mo 99994711
    typedef long long ll;
    using namespace std;
    int is1=1,is2=1,all=3,base=1314,ord[4],ans,l[4];
    long long num[4][100010],bs[100010];
    bool vis[4];
    char s[4][100010];
    
    ll gethash(int x,int st,int l)
    {
        ll ans=0;
        ans=bs[100005-st]*(num[x][st+l-1]-(st==0? 0 : num[x][st-1]))%mo;
        return (ans%mo+mo)%mo;
    }
    
    bool in(int x,int y)
    {
        ll u,v;
        for (int i=0;i<l[y]-l[x];i++)
        {
    	u=gethash(y,i,l[x]);
    	v=num[x][l[x]-1]*bs[100005]%mo;
    	if (u==v) return 1;
        }
        return 0;
    }
    
    int mini(int x,int y)
    {
        ll u,v;
        int ans=0;
        for (int i=1;i<=min(l[x],l[y]);i++)
        {
    	u=gethash(x,l[x]-i,i);
    	v=gethash(y,0,i);
    	if (u==v) ans=i; 
        }
        return ans;
    }
    
    void hsh(int x)
    {
        for (int i=0;i<l[x];i++)
    	if (i) num[x][i]=(num[x][i-1]+(ll)(s[x][i]-'a'+1)*bs[i])%mo;
    	else num[x][i]=s[x][i]-'a'+1;
    }
    
    void dfs(int x)
    {
        if (x>3)
        {
    	ans=min(ans,l[1]+l[2]+l[3]-mini(ord[1],ord[2])-mini(ord[2],ord[3]));
    	return ;
        }
        for (int i=1;i<=3;i++)
    	if (!vis[i])
    	{
    	    vis[i]=1;
    	    ord[x]=i;
    	    dfs(x+1);
    	    vis[i]=0;
    	}
    }
    
    void st()
    {
        if (l[1]>l[2]) swap(l[1],l[2]),swap(s[1],s[2]);
        if (l[2]>l[3]) swap(l[2],l[3]),swap(s[2],s[3]);
        if (l[1]>l[2]) swap(l[1],l[2]),swap(s[1],s[2]);
    }
    
    int main()
    {
        ans=0x7fffffff;
        bs[0]=1;
        for (int i=1;i<=100005;i++) bs[i]=bs[i-1]*base%mo;
        scanf("%s%s%s",s[1],s[2],s[3]);
        l[1]=strlen(s[1]);
        l[2]=strlen(s[2]);
        l[3]=strlen(s[3]);
        st();
        hsh(1);
        hsh(2);
        hsh(3);
        if (in(1,2)) is1=0,all--;
        if (in(2,3)) is2=0,all--;
        if (is1 && in(1,3)) is1=0,all--;
        if (all==1)
        {
    	printf("%d
    ",l[3]);
    	return 0;
        }
        if (all==2)
        {
    	if (!is2 && is1) swap(s[1],s[2]),swap(l[1],l[2]);
    	hsh(2);
    	hsh(3);
    	printf("%d
    ",l[2]+l[3]-max(mini(2,3),mini(3,2)));
        }
        else
        {
    	dfs(1);
    	printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    C# 多线程编程及其几种方式
    多态有几种表现形式
    闭包的理解
    C# 泛型类型约束 where
    HTML扩展--HTMLTestRuner HTML测试报告
    编写web自动化测试
    unittest单元测试框架之认识unittest
    自动化测试模型
    处理HTML5视频播放、滑动解锁
    操作Cookie调用JavaScript
  • 原文地址:https://www.cnblogs.com/mrha/p/8024224.html
Copyright © 2011-2022 走看看