【ybt高效进阶2-1-4】字符串环

字符串环

题目链接:ybt高效进阶2-1-4

题目大意

就是有两个字符串,问你最长连续公共子串的长度。

思路

这道题主要就是环的问题。

那我们就把环破开,具体方法就是再复制一遍。
(注意,最大的长度还是原来字符串的最小的那一个)

然后首先看公共子串的长度(应该是可以枚举,但是我这里用了二分),然后枚举两个序列是选取哪两段,然后配对。

代码

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

int an, bn, l, r, ans, mid;
char a[601], b[601];
bool yes;

bool ch(int mid) {
    
    
	if (mid == 0) return 1;
	for (int i = mid; i <= bn; i++) {
    
    //b序列选 i-mid+1~i 这一段
		for (int j = mid; j <= an; j++) {
    
    //a序列选 j-mid+1~j 这一段
			yes = 1;
			for (int k = 0; k < mid; k++)//逐位判断是否相同
				if (b[i - k] != a[j - k]) {
    
    
					yes = 0;
					break;
				}
			if (yes) return 1;
		}
	}
	return 0;
}

int main() {
    
    
	scanf("%s %s", a + 1, b + 1);
	an = strlen(a + 1);
	bn = strlen(b + 1);
	
	if (bn > an) {
    
    
		swap(a, b);
		swap(an, bn);
	}
	
	for (int i = an + 1; i <= 2 * an; i++)//因为是环,就把它复制一遍
		a[i] = a[i - an];
	an *= 2;
	for (int i = bn + 1; i <= 2 * bn; i++)
		b[i] = b[i - bn];
	bn *= 2;
	
	l = 0;
	r = bn / 2;//因为你就算复制了一遍,最大的还是原来的长度
	while (l <= r) {
    
    
		mid = (l + r) >> 1;
		if (ch(mid)) {
    
    
			ans = mid;
			l = mid + 1;
		}
		else r = mid - 1;
	}
	
	printf("%d", ans);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43346722/article/details/112852559