HDU 3294 马拉车算法

该算法,对于任意一个在最后 串中的pos位置,都对应原串的(pos-malache[pos]+2)/2-1位置,且长度为为malache[pos]-1


这样就很容易直接求出所有回文位置了。


模板依旧用上一篇文章的模板


/*
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
#include <tr1/unordered_map>
#include <ctime>
using std::tr1::unordered_map;
*/

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;

/*
   using std::sort;
   using std::bitset;
   using std::max;
   using std::cout;
   using std::stack;
   using std::cin;
   using std::endl;
   using std::swap;
   using std::pair;
   using std::vector;
   using std::set;
   using std::map;
   using std::multiset;
   using std::queue;
   using std::greater;
   using std::string;
   using std::priority_queue;
   using std::max_element;
   using std::min_element;

   using __gnu_pbds::pairing_heap_tag;
   __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> heap;
#define Hash unordered_map
*/
#define pr(x) cout<<#x<<" = "<<x<<" "
#define prln(x)    cout<<#x<<" = "<<x<<endl

#define lson o*2, L, M
#define rson o*2+1, M + 1,R

//const int maxn = 210000;
const int maxn = 400000+100;

//对于text[],返回一个out[],out[i],表示从i开始,可以向右多远是合法的




#include <typeinfo>
	template<typename T>
void manacher(T text[], int len, int malache[], T str[])  
{  
	T inf, space;
	if (typeid(T).name() == typeid(char).name())
	{
		inf= -128;
		space = 2 - 127;
	}
	if (typeid(T).name() == typeid(int).name())
	{
		inf= - 0x3f3f3f3f;
		space = 2 -0x3f3f3f3f;
	}
	int l = 0;
	str[l++] = inf;
	str[l++] = space;
	for (int i = 0; i < len; ++ i)
	{
		str[l++] = text[i];
		str[l++] = space;
	}
	str[l] = inf + 1;
	int mx=0, id=0;//mx:最远匹配距离,id:最远距离对应的坐标的下标
	for (int i = 0; i < l; ++ i)
	{
		malache[i] = mx > i ? min(malache[2 * id - i], mx - i) : 1;
		while (str[i + malache[i]] == str[i - malache[i]])	malache[i] ++ ;
		if (i + malache[i] > mx)
		{
			mx = i + malache[i];
			id = i;
		}
	}  
}

char flag[10],input[400000 + 200];
int malache[400000 + 200];
char str[400000 + 200];

int main()
{
	while (scanf(" %s %s ", flag, input) == 2)
	{
		char ch = flag[0];
		int len = strlen(input);
		for (int i = 0; i != len; ++ i)
		{
			input[i] = (input[i]-ch+26)%26 + 'a';
		}
		manacher(input, len, malache, str);
		int pos=0, ans=0;
		for (int i = 0; i < 2 * len + 2; i ++)
		{
			if (malache[i]>ans)
			{
				ans = malache[i];
				pos = i;
			}
		}
		ans--;
		if (ans==1)
			printf("No solution!\n");
		else
		{
			if (pos%2==0)
			{
				//如果是偶数,则为pos/2-1为中点
				//pos-malache[pos]+1为起点
				//起点为 (pos-malache[pos]+1)/2-1为起点,长为malache[pos]-1
				printf("%d %d\n", (pos-malache[pos]+2)/2-1, (pos-malache[pos]+2)/2-1+ans-1);
			}
			else
			{
				//如果是奇数,则说明为aa或者baab这样的回文串
				//(pos-malache[pos])/2为起点,长度为malache[pos]-1
				printf("%d %d\n", (pos-malache[pos]+2)/2-1, (pos-malache[pos]+2)/2-1+ans-1);
			}
			for (int i = (pos-malache[pos])/2; i <= (pos-malache[pos])/2 + ans - 1; ++ i)
				printf("%c", input[i]);
			printf("\n");
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值