[ CODEVS ] 1568 奶牛回文

裸Manacher算法题,开一个rank[i]记录映射关系。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<iterator>
const int maxn = 20000 + 10;
using namespace std;
char s[maxn], in[maxn];
int rank[maxn], p[maxn], id, mx;
bool check(char t) {
	if(t >= ‘a‘&& t <=‘z‘||t >= ‘A‘&&t <= ‘Z‘) return true;
	else return false;
}
int main() {
	string src, dst;
	for(int i = 0; ; i++) {
		scanf("%c", &in[i]);
		if(in[i] == EOF) break;
	}
	src = in;
	transform(src.begin(), src.end(), back_inserter(dst), ::toupper);
    transform(src.begin(), src.end(), dst.begin(), ::tolower);
    int len = 0;
    for(int i = 0; i < dst.length(); i++) {
		if(check(dst[i])) { s[len] = dst[i]; rank[len] = i; len++;}
	}
	len *= 2;
	for(int i = len; i >= 0; i--) {
		if(i & 1) s[i] = s[i / 2];
		else s[i] = ‘#‘;
	}
	int pmax = 0;
	for(int i = 0; i <= len; i++) {
		if(i >= mx) p[i] = 1;
		else p[i] = min(mx - i + 1, p[2 * id - i]);
		while(i - p[i] >= 0 && i + p[i] <= len && s[i + p[i]] == s[i - p[i]]) p[i]++;
		if(i + p[i] - 1 >= mx) {
			mx = i + p[i] - 1;
			id = i;
		}
		pmax = max(pmax, p[i]);
	}
	int k;
	for(k = 0; k < len; k++) {
		if(p[k] == pmax) break;
	}
	int l = k - (p[k] - 1); int r = k + (p[k] - 1); r--;
	l /= 2, r /= 2;
	l = rank[l];
	r = rank[r];
	cout << pmax - 1 << endl;
	for(int i = l; i <= r; i++) cout << src[i];
	return 0;
}

  

时间: 2024-10-11 11:53:46

[ CODEVS ] 1568 奶牛回文的相关文章

codevs 1045 回文数

题目描述 Description 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. 例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数. 又如:对于10进制数87: STEP1:87+78  = 165                  STEP2:165+561 = 726 STEP3:726+627 = 1353                STEP4:1353+3531 = 4884 在这里的一步是指进行了一次N进制的加法

回文质数 USACO

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数.写一个程序来找出范围[a,b](5<=a<b<=100,000,000)间的所有回文质数; 因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数.写一个程序来找出范围[a,b](5<=a<b<=100,000,0

16-最少回文数组

Splits the string 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string. A sequence of characters is a palindrome if it is the same written forwards and backwards. Fo

最少回文串--牛客网(秋招备战专场三模)-C++方向

题目描述:一个字符串从左向右和从右向左读都完全一样则是回文串,给定一个字符串,问该字符串中的字符所能组成的最少的回文串的个数为多少 解题思路:如果一个字符出现的次数为偶数,则必能组成回文串,如果一个字符出现奇数次,只能自己组成回文串,题目中问最少的回文串数目,即求出现次数为奇数次的字符个数即可,定义a存储每个字符出现的次数,统计出现奇数次的字符的个数,即为输出 1 #include <iostream> 2 #include <string> 3 using namespace s

回文判断

一个整形数是否是回文 also leetcode 9 Palindrome Number要求空间复杂度O(1)按位判断一般是/和%的游戏,首先取首位 a/h (h是最接近a的10的次方,比如12321,h预计算出是10000), 再取末位a%10; 比较首位和末位是否相等,不等就返回false; 如图: 然后舍弃掉已经比较过的两个位数,从a中去掉首尾 12321 --> 232. a = a % h; // 去掉首 a = a /10; //去掉尾 h = 100; // 因为已经去掉了两位 如

判断一个数是否为回文数

#include <stdio.h> int is_palindromic(int num) {  char _old = num;  char _new = 0;  while (num)  {   _new = _new * 10 + (num % 10);   num = num / 10;  }  if (_new == _old)  {   return 1;  }  else  {   return 0;  } } int main() {  int num = 0;  scanf

判断一个字符串是否为回文字符串

#include <stdio.h> #include <assert.h> #include <string.h> int is_pal_str(const char *p) {  assert(p);  int len = strlen(p);  const char *start = p;  const char *end = p+len - 1;  while (start < end)  {   if (*start == *end)   {    st

LeetCode 9 Palindrome Number (回文数)

翻译 确定一个整数是否是回文数.不能使用额外的空间. 一些提示: 负数能不能是回文数呢?(比如,-1) 如果你想将整数转换成字符串,但要注意限制使用额外的空间. 你也可以考虑翻转一个整数. 然而,如果你已经解决了问题"翻转整数(译者注:LeetCode 第七题), 那么你应该知道翻转的整数可能会造成溢出. 你将如何处理这种情况? 这是一个解决该问题更通用的方法. 原文 Determine whether an integer is a palindrome. Do this without ex

要求循环输入一个数,判断是否为回文数

import java.util.Scanner; public class HuiWenShu { public static void main(String[] args) { Scanner input = new Scanner(System.in); char c = 'y'; //初始化c为y,为下面的循环做好准备 while(c == 'y'){ while(c == 'y'){ System.out.println("请随意输入一个大于三位的奇位数"); //回文数属