Atcoder Panasonic Programming Contest 2020 E Three Substrings 字串交叠+字串拼接

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值