题意:
给定两个串(串长都小于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;
}