Panasonic Programming Contest 2020 比赛人数6617 慢,比赛开始后10分钟才看到题目,比赛题目比ABC要灵活些
Atcoder Panasonic Programming Contest 2020 E Three Substrings 字串交叠+字串拼接
总目录详见https://blog.csdn.net/mrcrack/article/details/104454762
在线测评地址https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_e
思路同https://www.cnblogs.com/zdragon1104/p/12496988.html
题解:以字符串a为基准,相当于看字符串b,c在a的哪个位置,处理出ab,ac,bc,字符串偏移x是否满足要求,然后枚举b,c的偏移即可。
样例局部模拟如下
a?c a串
der b串
cod c串
der只能拼接在0,1,2,3位置,或者,der只能拼接在9,10,11,12,13,14位置
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
a ? c
d e r
1 ab[6]=1的由来
a ? c
d e r
1 ab[5]=1的由来
a ? c
d e r
1 ab[4]=1的由来
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
a ? c
d e r
1 ab[7]=1的由来
a ? c
d e r
1 ab[6]=1的由来
a ? c
d e r
1 ab[5]=1的由来
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
a ? c
d e r
1 ab[8]=1的由来
a ? c
d e r
1 ab[7]=1的由来
a ? c
d e r
1 ab[6]=1的由来
思路同https://blog.csdn.net/qq_43682148/article/details/104873271?fps=1&locationNum=2
计算答案时,b相对位置为i,c相对位置为j,则c相对于b的位置为j-i(画图易得)
AC代码如下
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 2010
using namespace std;
char a[maxn],b[maxn],c[maxn];
bool ab[maxn+maxn+maxn+maxn+maxn],ac[5*maxn],bc[5*maxn];//bca,cba,abc,acb
int match(char a,char b){
if(a==b||a=='?'||b=='?')return 1;
return 0;
}
int main(){
int i,j,A,B,C,L,R,ans=5*maxn;
scanf("%s%s%s",a,b,c);
A=strlen(a),B=strlen(b),C=strlen(c);
for(i=0;i<A;i++)
for(j=0;j<B;j++)
if(!match(a[i],b[j]))ab[i-j+2*maxn]=1;//标记不匹配位置
for(i=0;i<A;i++)
for(j=0;j<C;j++)
if(!match(a[i],c[j]))ac[i-j+2*maxn]=1;
for(i=0;i<B;i++)
for(j=0;j<C;j++)
if(!match(b[i],c[j]))bc[i-j+2*maxn]=1;
for(i=-(B+C);i<=A+max(B,C);i++)//i记录b串首字母相对a串位置
for(j=-(B+C);j<=A+max(B,C);j++)//j记录c串首字母相对a串位置
if(!ab[i+2*maxn]&&!ac[j+2*maxn]&&!bc[j-i+2*maxn]){//j-i记录c串首字母相对b串位置
L=min(0,min(i,j)),R=max(A,max(B+i,C+j));//min(i,j)>0表示在a串内部匹配,故取0;B+i,或C+j可能还小于A
ans=min(ans,R-L);
}
printf("%d\n",ans);
return 0;
}