题意:
给定两个串(串长都小于1e5) , 从第一个串0位置开始如果该位置开始与第二个串“匹配”(至多两个位置字母不同) , 记为一个可行点, 那么求最小可行点。
分析:
直接枚举位置,我们发现当前被枚举的点,有一个确定性因素,即把该点当做了起始匹配位置(这一点非常重要),那么最长会有多长哪,贪心的想法想一下,即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long llu; #define clr(a , x) memset(a , x, sizeof(a)); #define rep(i , n) for(int i=0; i<(int)n ; i++) #define rep1(i , x, y) for(int i=(int)x;i<=(int)y;i++) #define repd(i , y ,x) for(int i=(int)y;i>=(int)x;i--) const int N = 1e5 + 100; const llu base = 123; llu ha1[N] , ha2[N] ,POW[N]; char s1[N],s2[N]; llu get(llu* s , int i,int len){ return s[i] - s[i+len]*POW[len]; } int n,m; llu cal(int i, int j){ int x = 0 , y = min(m - j , n - i) + 1; while(x < y){ int mid = (x + y)>>1; if(get(ha1 , i , mid) == get(ha2 , j ,mid)) x = mid + 1; else y = mid; } return x-1; } void init(){ scanf("%s %s",s1 , s2); n = strlen(s1) , m = strlen(s2); ha1[n] = 0; repd(i , n-1 , 0) ha1[i] = ha1[i+1]*base + s1[i] - 'a'; ha2[m] = 0; repd(i , m-1 , 0) ha2[i] = ha2[i+1]*base + s2[i] - 'a'; } int solve(){ if(n < m) return -1; rep(i ,n - m + 1){ int cnt = 0 , num = 0 , x = i , y = 0; rep(j , 3){ int td = cal(x , y); x+=td; y+=td; if(j < 2) ++x , ++y; if(y >= m){ return i; } } } return -1; } int main() { POW[0] = 1; rep1(i , 1 , N-1) POW[i] = POW[i-1]*base; int T , kase = 1; scanf("%d",&T); while(T--){ init(); printf("Case #%d: %d\n",kase++,solve()); } return 0; }