9.9 华为笔试

t2

大概思路:题目要求的是,第一个完美排列出现的位置,然后看数据范围,给出的数值最大是5,那么我们可以考虑,把这两个串合成一个,A[i] = a[i] * 6 + b[i];,
对于给出的大串也是如此B[i] = c[i] * 6 + d[i]; 然后就是直接kmp匹配,找到出现的第一个位置,变成kmp模板题
具体看代码

using namespace std;

const int mn = 1e6 + 10;

int n, m;
int nx[mn];

void cal_next(int b[])
{
	memset(nx, 0, sizeof nx);
	nx[0] = -1;
	int k = -1;
	int j = 0;
	while (j < m)
	{
		if (k == -1 || b[j] == b[k])
		{
			j++;
			k++;
			nx[j] = k;
		}
		else
			k = nx[k];
	}
}

int KMP(int a[], int b[])
{
	cal_next(b);

	int i = 0, j = 0;
	while (i < n && j < m)
	{
		if (j == -1 || a[i] == b[j]) i++, j++;
		else j = nx[j];
	}
	if (j >= m) return i - m + 1;
	else return 0;
}

int a[mn], b[mn];
int c[mn], d[mn];
int A[mn], B[mn];

int main()
{
	cin >> m;
	for (int i = 0; i < m; i++) scanf("%d", &a[i]);
	for (int i = 0; i < m; i++) scanf("%d", &b[i]);
	for (int i = 0; i < m; i++)
		A[i] = a[i] * 6 + b[i];


	cin >> n;
	for (int i = 0; i < n; i++) scanf("%d", &c[i]);
	for (int i = 0; i < n; i++) scanf("%d", &d[i]);
	for (int i = 0; i < n; i++)
		B[i] = c[i] * 6 + d[i];

	cout << KMP(B, A) << endl;

	return 0;
}

/*
2
3 4
3 4
8
0 0 0 0 3 4 0 0
0 0 0 0 3 4 0 0

*/
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13642147.html