CDOJ 1305 Just a Magic String

子串只有10^6,所以可以直接去匹配,不管什么规律,但是,母串要到4*10^6,才能考虑到10^6的串的所有情况,具体,用小数据列举一下就可以发现。

然后我用的是KMP,貌似暴力匹配也能过,另,正解貌似是DFS


代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 4194304
char s1[maxn], s2[1000003];
int then[1000003];
char idx[256];
int n1, n2;
void init_s1()
{
	idx['a'] = 'b', idx['b'] = 'a';
	s1[0] = 'a', s1[1] = 'b';
	int len = 2;
	while (len < maxn)
	{
		for (int i = 0; i < len; ++i)
			s1[len + i] = idx[s1[i]];
			
		len <<= 1;
	}
}
void get_then()
{
	int i = 0, j = -1;
	then[0] = -1;
	while (i < n2)
	{
		if (j == -1 || s2[i] == s2[j])
		{
			++i;
			++j;
			then[i] = j;
		}
		else
			j = then[j];
	}
}
int kmp()
{
	int t1 = 0, t2 = 0;
	while (t1<n1&&t2<n2)
	{
		if (t2 == -1 || s1[t1] == s2[t2])
		{
			t1++;
			t2++;
		}
		else t2 = then[t2];
	}
	if (t2 == n2)
		return t1 - t2 + 1;
	else
		return -1;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	scanf("%s", s2);
	n1 = maxn, n2 = strlen(s2);
	init_s1();
	get_then();
	/*for (int i = 0; i < 10; ++i)
		printf("%c", s1[i]);*/
	int ans = kmp();
	printf("%d\n", ans);
	//system("pause");
	//while (1);
	return 0;
}

你可能感兴趣的:(CDOJ 1305 Just a Magic String)