Power oj/2610[判断回文串]

题目链接【https://www.oj.swust.edu.cn/problem/show/2610】

题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e7,内存是4096KB。

题解:首先这1e7个字符是存不下的,1e71024=9765KB>4096kB。那么怎么办?字符串哈希,先对字符串的前半部分进行哈希,然后在对字符串后半部分进行哈希,如果两部分的哈希值相同,那么这个字符串就是回文串。

BKDRH哈希,哈希公式为has=has*seed+s[i],seed为31,131,1313,这里选择131。对于后半部分has+=pow(seed,i-1)*s[i]。但是这样哈希会有漏洞,需要更近一步的完善,我们用unsigned long long 存HAS值,所以他会自动取模(2^64-1),

对于前半部分我们维护两个HAS值,分别对两个不同的素数取模,后半部分也一样。那么我们就维护这两对哈希值,只有当这两对哈希值都分别相等的时候,我们才认为这两段字符串是相等的,也就是回文串。具体看代码。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const ULL modA = 1e9 + 7;
const ULL modB = 1e9 + 9;
ULL has[5], SEED = 131;
int N;
int main ()
{
    while(~scanf("%d", &N))
    {
        has[0] = has[1] = 0;
        has[2] = has[3] = 0;
        char s;
        char S[5];
        gets(S);
        for(int i = 1; i <= N / 2; i++)
        {
            s = getchar();
            ULL t = (ULL)s;
            has[0] = (has[0] * SEED + t) % modA;
            has[1] = (has[1] * SEED + t) % modB;
        }
        if(N % 2) s = getchar();
        ULL seed[3];
        seed[0] = seed[1] = seed[2] = (ULL)1;
        for(int i = 1; i <= N / 2; i++)
        {
            s = getchar();
            ULL t = (ULL)s ;
            has[2] = (has[2] + t * seed[0]) % modA;
            has[3] = (has[3] + t * seed[1]) % modB;
            seed[0] = seed[0] * SEED % modA;
            seed[1] = seed[1] * SEED % modB;
        }
        if(has[0] == has[2] && has[1] == has[3] )
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
时间: 2024-10-11 00:59:44

Power oj/2610[判断回文串]的相关文章

HDOJ/HDU 2163 Palindromes(判断回文串~)

Problem Description Write a program to determine whether a word is a palindrome. A palindrome is a sequence of characters that is identical to the string when the characters are placed in reverse order. For example, the following strings are palindro

LeetCode 5 迅速判断回文串的曼切斯特算法

题意 Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Link: https://leetcode.com/problems/longest-palindromic-substring/ 翻译 给定一个字符串s,要求它当中的最长回文子串.可以假设s串的长度最大是1000. 样例 Example 1: Input:

判断回文串

代码如下: package ClassDemo; import java.util.Scanner; public class CheckPalindrome { public static void main (String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter a string: "); String s = input.nextLine(); int low = 0; i

添加字符判断是否为回文串

题目:给定一个字符串,问是否能通过添加一个字母将其变为回文串. 提要:所有代码皆为C++语言. 看到题,首先想到如何判断回文串 注:回文串添加或删除指定字符一定还是回文串. 对于一个字符串,从左右两端开始,以此判断,直到读取超出字符串中间. 代码如下: #include<iostream> #include<string.h> using namespace std; bool JudgeReverseString(char *str) { //对比对应位置字符是否相同 int l

leetcode刷题1--动态规划法回文串2

题目是: Given a string s,partition s such that every substring of the partition is a palindrome Return tthe mininum cuts needed for a palindrome partitioning of s. For example,given s="aab" Return 1 since the  palindrome partition["aa",&q

例题9-7 划分成回文串 UVa11584

1.题目描述:点击打开链接 2.解题思路:本题要求划分回文串,且个数尽可能的少.可以用动态规划解决.先提前判断i~j是否构成回文串,时间复杂度是O(N^2),然后定义d(i)表示0~i-1划分成的回文串的最小个数.则状态转移方程为: d(i)=min(d(i),d(j)+1)(s[j...i]是回文串) 上式中,d(i)的初始值是i,这样每次判断只需要O(1)的时间,总时间复杂度是O(N^2).当然,判断回文串的过程可以和状态转移相结合,细节请参考第二份代码. 3.代码: #define _CR

最大回文串 变种

1 /** 2 * 求一个字符串的最大回文串,可以在两边和中间删除任意多个字符,使剩下的字符串为回文串 3 * 可以使用回溯法 4 */ 5 import java.util.Scanner; 6 7 public class Palindrome { 8 static int[] flag; 9 static int length; 10 static String s; 11 static int maxLength; 12 static String maxString; 13 14 pu

九章算法面试题48 分割回文串

九章算法官网-原文网址 http://www.jiuzhang.com/problem/48/ 题目 对于给定字符串,求最少需要几次划分,能够将字符串划分为若干子串,每个子串都是一个回文串.如abaab,需要至少1次划分,将字符串划分为:a|baab,每个部分均为回文串. 解答 这是一道典型的在字符串上进行分割的动态规划的问题.一般的状态表示方法如下:f[i]表示将前i个字符组成的子串进行划分,能够最少划分为多少个串,每个串都是回文串.那么有状态转移方程:f[i] = MIN(f[j] + 1,

判断回文链表

我们之前有两篇文章写了回文串和回文序列相关的问题. 寻找回文串的核心思想是从中心向两端扩展: string palindrome(string& s, int l, int r) { // 防止索引越界 while (l >= 0 && r < s.size() && s[l] == s[r]) { // 向两边展开 l--; r++; } // 返回以 s[l] 和 s[r] 为中心的最长回文串 return s.substr(l + 1, r - l