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
*/