日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hiho一下第一周 Hihocoder #1032 : 最长回文子串

發(fā)布時間:2024/9/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hiho一下第一周 Hihocoder #1032 : 最长回文子串 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

#1032 : 最長回文子串

時間限制:1000ms 單點(diǎn)時限:1000ms 內(nèi)存限制:64MB

描述

???小Hi和小Ho是一對好朋友,出生在信息化社會的他們對編程產(chǎn)生了莫大的興趣,他們約定好互相幫助,在編程的學(xué)習(xí)道路上一同前進(jìn)。

???這一天,他們遇到了一連串的字符串,于是小Hi就向小Ho提出了那個經(jīng)典的問題:“小Ho,你能不能分別在這些字符串中找到它們每一個的最長回文子串呢?”

???小Ho奇怪的問道:“什么叫做最長回文子串呢?”

???小Hi回答道:“一個字符串中連續(xù)的一段就是這個字符串的子串,而回文串指的是12421這種從前往后讀和從后往前讀一模一樣的字符串,所以最長回文子串的意思就是這個字符串中最長的身為回文串的子串啦~”

???小Ho道:“原來如此!那么我該怎么得到這些字符串呢?我又應(yīng)該怎么告訴你我所計算出的最長回文子串呢?

???小Hi笑著說道:“這個很容易啦,你只需要寫一個程序,先從標(biāo)準(zhǔn)輸入讀取一個整數(shù)N(N<=30),代表我給你的字符串的個數(shù),然后接下來的就是我要給你的那N個字符串(字符串長度<=10^6)啦。而你要告訴我你的答案的話,只要將你計算出的最長回文子串的長度按照我給你的順序依次輸出到標(biāo)準(zhǔn)輸出就可以了!你看這就是一個例子。”

良久,小Ho仍然沒有頭緒,于是只能向小Hi求助。

Hi清了清嗓子,緩緩說道:“讓我從簡單的說起吧,我給你一個字符串,你能不能告訴我它是不是一個回文串呢?

Ho回答道:“這個我當(dāng)然可以啦!只要將這個字符串反過來,然后比較和原來的字符串是不是一樣的不就行了?”

Hi追問道:“也就是說你想要新建一個字符串咯?”

Ho道:“那是當(dāng)然,不然怎么比較呢?”

Hi笑道:“但是你有沒有注意到你在比較原來的字符串A和新字符串B的時候,A的第一個字符就是B的最后一個字符,而A的最后一個字符就是B的第一個字符,那么這樣就比較了兩次是不是浪費(fèi)了效率呢?”

Ho恍然道:“似乎是這樣的!我知道了,我也不需要新建一個字符串了,我只需要比較A的第一個字符和最后一個字符是否相同,第二個字符和倒數(shù)第二個字符是否相同,以此類推,這樣就只要比較字符串長度的一半次數(shù)就行了是不是?”

Hi回答道:“沒錯!那你對于一個字符串,一一枚舉它的子串,然后判斷這個子串是不是回文子串,如果是的話就更新當(dāng)前保存的最長的那一個,是不是就可以了?”

Ho開心道:“是的!這個問題是不是就這么解決了?”

Hi嘆息道:“NONONO你這最多也就拿個60分吧。”

小Ho遺憾的說道:“才及格啊,那我要怎么多拿點(diǎn)分呢?”

Hi道:“不急不急,待我慢慢道來,你有沒有想過之前的解法有沒有什么問題?”

Ho問道:“有什么問題?”

Hi道:“你想想,如果一個字符串的[3, 7]這一段已經(jīng)不是回文子串了,[2, 8]這一段還有可能是回文子串么?

Ho驚道:“好像不可能,那我之前不是有很多的計算都白費(fèi)了,有沒有什么辦法來解決這個問題呢?我得好好想想!”言罷,小Ho沉思了起來。

良久,代表著成功的微笑出現(xiàn)來的小Ho的嘴邊:“我知道了!我在枚舉子串的時候換一種方式來進(jìn)行枚舉,不是枚舉它的起止位置而是嘗試枚舉子串的中心位置,然后再從小到大依次枚舉這個子串的長度,一旦發(fā)現(xiàn)已經(jīng)不是一個回文串了就繼續(xù)嘗試下一個中心位置,這樣,似乎就能夠避免掉很多問題呢!”

Hi贊許的點(diǎn)了點(diǎn)頭,說道:“沒錯,這樣的確會在一些情況下降低用于計算的時間呢,但是一個全是a的字符串,你這樣的枚舉方法似乎也沒有多大用處呢?不過這樣你也能拿個80分了哦!”

Ho點(diǎn)了點(diǎn)頭,說道:“沒錯,在最壞情況下,這種方法并沒有比之前的方法好到哪里去,但是我的直覺告訴我肯定有更加高效的方法來進(jìn)行計算呢,讓我再好好想想吧!。”

小Ho這一想就是三天,小Hi也是看不下去了,決定來開導(dǎo)開導(dǎo)小Ho:“小Ho,你有沒有想過,在之前的計算中,計算出以每一個位置為中心的最長回文子串的長度有沒有什么用呢?”

小Ho答道:“我想想,如果以第5個字符為中心的最長回文子串的長度是5的話,這就告訴了我[3, 7]這一段是一個回文子串,所以呢?”

小Hi繼續(xù)提示道:“假設(shè)這時候你想要計算以第6個字符為中心的最長回文子串的長度,你有沒有什么已知的信息了?”

小Ho邊想邊說道:“唔,首先第6個字符和第4個字符是一樣的,第7個字符和第3個字符是一樣的,而第5個字符本身就肯定和第5個字符一樣,那么如果[3, 5]這一段是回文子串的話,那么[5, 7]這一段肯定也是回文子串。也就是說,如果令f[i] 表示以第i個字符為中心的最長回文子串的長度,我們就會有f[i] >= f[i–2]?”

“不對,還要考慮到f[i – 1]的值,如果f[i – 1]太小就沒有意義了,應(yīng)該是f(i)≥min?{f(i-2), f(i-1)-2}。”小Ho接著補(bǔ)充道。

“沒錯,但是還有一個問題,如果此時我告訴你f(5) = 1,但是f(4) = 7, f(2) = 3呢?”小Hi追問道。

小Ho想了想,回答道:“理論上來說,我可以通過這些信息知道f(6)>=3,但是由于f(5)=1所以我只能計算出來f(6)>=-1我知道了,我不應(yīng)該是通過f(i – 1)來輔助計算,而是通過使得右邊界(j + f(j) / 2)最大的那個j來輔助計算才是,所以公式將變成 f(i) ≥ min{f(2*j-i) , f(j) -2*(i-j)}這種形式了!”

Hi繼續(xù)問道:“那知道了這個公式之后,你打算怎么做呢?”

小Ho想也沒想便道:“這簡單,我只要在之前枚舉中心位置那種方法的基礎(chǔ)上,統(tǒng)計使得回文串右邊界(j + f(j) / 2)最大的那個j,然后再計算每一個i的時候,都可以通過f(i)≥min?{f(2*j-i), f(j)-2*(i-j)}這個公式來知道f(i)的一個最小值,這樣即使是在我們所提到的那種最壞情況下,也可以節(jié)省掉很多不必要的計算呢~

一晃就是一周過去了,小Hi還是沒有看到小Ho寫的程序,于是決定上門去問問。到了小Ho家,小Hi驚訝的發(fā)現(xiàn)小Ho對著電腦屏幕,一臉郁悶的樣子,于是他走上前問道:“小HoHo,你怎么了啊?”

Ho一點(diǎn)精神也沒有的回答道:“就是上周的那個回文子串的程序啊,我寫的時候發(fā)現(xiàn)我們當(dāng)時考慮的解決方法只能處理長度為奇數(shù)的回文子串,長度為偶數(shù)的回文子串似乎要進(jìn)行一點(diǎn)點(diǎn)細(xì)微的修改,但是這樣修改過后就不能用我們最后寫出的那個公式來互相幫助進(jìn)行運(yùn)算了,要進(jìn)行很復(fù)雜的討論,我就是一直在想有沒有很優(yōu)美的方法能來解決這個問題。”

Hi驚訝道:“你就想這個想了一周么?我猜你一定是繞進(jìn)了分類討論的這個胡同里走不出來了,為什么不想想有沒有別的解決方法呢?”

Ho問道:“還有什么解決方法呀?”

Hi答道:“既然長度為偶數(shù)的回文子串不好處理,我們?yōu)槭裁床蝗サ暨@些回文子串,只處理長度為奇數(shù)的回文子串呢?”

Ho嘆息道:“但是長度為偶數(shù)的回文子串也可以是答案啊!”

除非……”小Hi插嘴道。

“除非什么?”小H問道。

“你將所有的長度為偶數(shù)的回文子串都變成長度為奇數(shù)的回文子串啊,你想想之所以是為偶數(shù),那是因為沒有一個中心字符,但是如果我們在原來字符串的基礎(chǔ)上,在任意兩個相鄰的字符間都插入一個特殊字符,是不是無論是原來字符串中長度為奇數(shù)的回文子串還是長度為偶數(shù)的回文子串,在新的字符串中都有一個長度為奇數(shù)的回文子串與之進(jìn)行對應(yīng)呢?”

“哦!我了解了,這樣我只需要對新的字符串按照我們之前的算法進(jìn)行計算,統(tǒng)計出的最長回文子串將那些特殊字符去掉之后,就是原來字符串里的最長回文子串了。”小Ho開心的笑道,一連幾天的郁悶也是一掃而空。

“但是要注意哦,我們希望得到的最長是原來字符串里的最長,而不是新字符串里的最長,畢竟特殊字符的個數(shù)會因為中心字符是不是特殊字符而有差別的哦。”小Hi提醒道。

“恩恩,這樣我總能拿到滿分了吧?”

“沒錯呢!”

樣例輸入
3 abababa aaaabaa acacdas
樣例輸出
7 5 3
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<cmath> #define L 2000050 using namespace std; char s1[L],s2[L]; int cnt[L],l1,l2; int main(){int ans,t,i,j;//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);for(scanf("%d",&t);t--;){scanf("%s",s1);l1=strlen(s1);l2=0;s2[l2++]='$';s2[l2++]='#';for(i=0;i<l1;i++){s2[l2++]=s1[i];s2[l2++]='#';}s2[l2]='\0';memset(cnt,0,sizeof cnt);for(i=1,j=0;i<l2;i++){if(cnt[j]+j>i)cnt[i]=min(cnt[2*j-i],cnt[j]-(i-j));else cnt[i]=1;for(cnt[i];s2[i-cnt[i]]==s2[i+cnt[i]];cnt[i]++) ;if(i+cnt[i]>j+cnt[j])j=i;}ans=0;for(i=0;i<l2;i++)if(ans<cnt[i])ans=cnt[i];printf("%d\n",ans-1);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的hiho一下第一周 Hihocoder #1032 : 最长回文子串的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。