• 2019浙江省赛 Strings in the Pocket【manacher】


    Strings in the Pocket

    题目链接

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012

    题意

    给你两个字符串,问有多少种方法能使翻转a中一个的子串后能够和b相同

    题解

    分两种情况

    1. a和b相同:用马拉车求回文子串个数
    2. a和b不同:记录第一个和最后一个a不同于b的位置L和R,判断[L,R]是不是回文串,如果不是,答案为0;如果是,匹配a的前部和b的后部、a的后部和前部,看能匹配几次

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define scac(x) scanf("%c",&x)
    #define sca(x) scanf("%d",&x)
    #define sca2(x,y) scanf("%d%d",&x,&y)
    #define sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define scl(x) scanf("%lld",&x)
    #define scl2(x,y) scanf("%lld%lld",&x,&y)
    #define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
    #define pri(x) printf("%d
    ",x)
    #define pri2(x,y) printf("%d %d
    ",x,y)
    #define pri3(x,y,z) printf("%d %d %d
    ",x,y,z)
    #define prl(x) printf("%lld
    ",x)
    #define prl2(x,y) printf("%lld %lld
    ",x,y)
    #define prl3(x,y,z) printf("%lld %lld %lld
    ",x,y,z)
    #define ll long long
    #define LL long long
    inline ll read(){ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;}
    #define read read()
    #define pb push_back
    #define mp make_pair
    #define P pair<int,int>
    #define PLL pair<ll,ll>
    #define PI acos(1.0)
    #define eps 1e-6
    #define inf 1e17
    #define INF 0x3f3f3f3f
    #define MOD 998244353
    #define mod 1e9+7
    #define N 2000005
    const int maxn=2e5+5;
    int t;
    int len,cnt;
    char a[N],b[N],c[N],tmp[N<<1];
    int Len[N<<1];
    
    int init(char *st)
    {
        int i,len=strlen(st);
        tmp[0]='@';
        for(i=1;i<=2*len;i+=2)
        {
            tmp[i]='#';
            tmp[i+1]=st[i/2];
        }
        tmp[2*len+1]='#';
        tmp[2*len+2]='$';
        tmp[2*len+3]=0;
        return 2*len+1;
    }
    void manacher(char *st,int len)
    {
        ll ans=0;
        int mx=0,po=0;
        int l=0,r=0;//
        for(int i=1;i<=len;i++)
        {
            if(mx>i)
                Len[i]=min(mx-i,Len[2*po-i]);
            else
                Len[i]=1;
            while(st[i-Len[i]]==st[i+Len[i]])
                Len[i]++;
            if(Len[i]+i>mx)
            {
                mx=Len[i]+i;
                po=i;
            }
            l=(i-1)/2-(Len[i]-1)/2;
            r=(i-1)/2+(Len[i]-1)/2;
            if(Len[i]&1) r--;
            ans+=((r-l+2)/2);
        }
        printf("%lld
    ",ans);
        return ;
    }
    int main(){
      t = read;
      while(t--){
        scanf("%s",a);
        scanf("%s",b);
        if(strcmp(a, b) == 0) {
    	     int len = init(a);
    	     manacher(tmp, len);
        	 continue;
        }
        len = strlen(a);
        int l = 0, r = len-1;
        while(l < len){
          if(a[l] != b[l])break;
          l++;
        }
        while(r >= 0){
          if(a[r]!=b[r])break;
          r--;
        }
        strcpy(c,a);
        int tot = l;
        for(int i = r; i >= l; i--)
          c[tot++] = a[i];
        int ans = 1;
        for(int i = 0; i < len; i++){
            if(b[i] != c[i]){
                ans = 0;
                break;
            }
        }
        if(ans){
          l--,r++;
          while(l >=0 && r < len){
            if(a[l] != b[r] || a[r] != b[l])
              break;
            ans++;
            l--;r++;
          }
        }
        pri(ans);
      }
      return 0;
    }
    
    
  • 相关阅读:
    微信小程序日期插件默认获取延后时间示例
    【SpringBoot2 从0开始】底层注解
    【SpringBoot2 从0开始】实现自动配置的过程
    【SpringBoot2 从0开始】开发世界著名程序体验 springboot
    【SpringBoot2 从0开始】springboot 与 spring
    【SpringMVC 从 0 开始】使用注解方式配置 SpringMVC
    【SpringMVC 从 0 开始】异常处理器
    【SpringMVC 从 0 开始】拦截器介绍
    【SpringMVC 从 0 开始】文件上传和下载
    【SpringMVC 从 0 开始】HttpMessageConverter 报文信息转换器
  • 原文地址:https://www.cnblogs.com/llke/p/10785812.html
Copyright © 2020-2023  润新知