哈希表判断回文数的应用

本文介绍了一种计算字符串和谐度的方法,通过优化回文串的判断过程来提高效率,适用于字符串长度不超过500万的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.第二饭堂 (hw.pas/c/cpp)
问题描述
    由于一饭班长表示各种鸭梨,美丽的*中决定历史性地启用第二饭堂。
    而部分领导觉得,二饭依山傍水,环境优美,未免有不和谐的事情(你懂的)发生,决定到二饭巡视同学们用餐时的就座情况。
    为了应付这一情况,同学们决定联合起来“布阵”。     方便起见,同学们已经把座位情况抽象成一个长度为n的仅含数字及字母的字符串,他们想请你帮忙算算这个字符串的和谐程度。
    已知一个字符串被称为k-回文串的充要条件是它自身是回文串,并且它长为⌊n/2⌋(下取整)的前缀和后缀是(k-1)-回文串。根据定义,任意字符串(包括空串)都是0-回文串。
    一个字符串的回文度数就是这个字符串的k的最大值。

    而对于一个给定的字符串,它的和谐程度就是其所有前缀的回文度数之和。     你的任务就是算出这个和谐程度具体是多少。

输入
    一行一个仅包含数字和字母的字符串。 
输出
    一行一个整数表示这个字符串的和谐高度。
 
输入输出样例

hw.in

abacaba 

hw.out
6
数据规模

对于30%的数据字符串长度不超过1000

对于70%的数据字符串长度不超过100000

对于100%的数据字符串长度不超过5000000 

首先关于和谐程度,是一个递推关系:F(x)=F(x/2)+1

但是这题一看数据就非常,然后我还是义无反顾的暴搜了

#include<cstdio>
#include<cstdlib>
#include<cstring>

int a[5000001],h[5000001],n,l,ans;

char s[5000001];

int main()
{
    int i,j;
    void hw(int m);
    int check(int m);
    
    freopen("hw.in","r",stdin);
    freopen("hw.out","w",stdout);
    
    gets(s);
    n=strlen(s);
    h[1]=1;
    ans=1;
    for(i=1;i<=n;i++)a[i]=s[i-1];
    for(i=2;i<=n;i++)hw(i);
      for(i=2;i<=n;i++)ans=ans+h[i];

    printf("%d\n",ans);
    
    fclose(stdin);
    fclose(stdout);
    return 0;  
}

int check(int m)
{
    int p,q,f;
    p=1;q=m;f=1;
    while(p<=q)
    {
      if(a[p]!=a[q])f=0;
      p++;q--;                  
               }
    return f;    
}


void hw(int m)
{
    if (check(m)==0)h[m]=0;
    else h[m]=h[m/2]+1;         
}

这样的话可以过七个点,主要时间是花在判断回文上。如何才能更有效更快的判断回文?

#include <iostream>
#include <cstdio>

using namespace std;

char s[5000010];
int f[5000010];

int main(){
	freopen("hw.in","r",stdin);
	freopen("hw.out","w",stdout);
	scanf("%s", s);
	int l=0, r=0, e=1, ans=0;
	for (int i=0; s[i]; i++){
		l=l*107+s[i];
	 	r=r+s[i]*e; e*=107; 
		if (l==r) f[i+1]=f[(i+1)/2]+1;
		ans+=f[i+1];
	}
	cout<<ans<<endl;
return 0;
}
对于每一个回文计算一个哈希值


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值