1. 程式人生 > >回文密碼

回文密碼

getchar ret color 範圍 數據 pass 一行 c++ bit

T2.回文密碼password.cpp/pas/in/out

時間限制:1s

空間限制:256MB

伊利斯.逐星:多虧了你的相助,我們通過了第一層。那些蜘蛛真是另令人作嘔。現在,我們來到了城堡二層,但是……恐怕又要麻煩你了。

布萊恩.銅須:你猜猜我們看到了什麽?烏瑟爾!我的好朋友,他的屍體就這麽被克爾蘇加德轉化成為了亡靈!還被凍在冰塊裏!我一定要找到這個可惡的死靈法師,把他砸成肉餅!

芬利.莫格頓:%^&##@#%^

(旁邊還有克爾蘇加德留給我們的謎題!上面寫著……)

雷諾.傑克遜:糟了!我們必須在一秒內解開密碼,否則……烏瑟爾將會從冰雕裏……解放出來……將我們殺掉。

題目描述:

他們又遇到麻煩了,現在需要你幫助他們解開克爾蘇加德的密碼。

有這樣一串數字和若幹次詢問,對於每次詢問,求出該詢問區間的最長回文子串長度,所有的結果的組合就是通往下一層的密碼

數據輸入:

第一行n表示數字串長度,第二行一串長度為n的數字串(數字範圍0~9)。第三行m表示詢問的次數,第4~4+m-1行每行一組LiRi表示詢問區間。

數據輸出:

m行,每行對應一個詢問。

輸入樣例:

10

1 2 3 4 5 5 4 3 2 1

2

1 10

2 9

輸出樣例:

10

8

數據範圍:

0<n<=100000,0<m<=1000000|Ri-Li|<=20

30%n,m<=200;

30%~60%,n,m<=2000;

2014級學長老爺子(馮俊傑)出的題,質量還是相當高的,是一個dpf[i][j]表示從i開始長度為j的序列中最長的回文序列的長度,轉移方程為

if(f[i+1][j-2]==j-2&&a[i]==a[i+j-1])

f[i][j]=j;

else

f[i][j]=max(f[i+1][j-1],f[i][j-1]);

長度是外循環。

#include<bits/stdc++.h>
using namespace std;

int n,m;
int a[201000];
int f[201000][210];

void
in(int &x) { char c=getchar();x=0; while(c<0||c>9)c=getchar(); while(c>=0&&c<=9)x=x*10+c-0,c=getchar(); } void out(int x) { if(x>9) out(x/10); putchar(x%10+0); } int main() { freopen("password.in","r",stdin); freopen("password.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) in(a[i]); for(int i=1;i<=n;i++) f[i][1]=1; for(int j=2;j<=n&&j<=200;j++) for(int i=1;i+j-1<=n;i++) { if(f[i+1][j-2]==j-2&&a[i]==a[i+j-1]) f[i][j]=j; else f[i][j]=max(f[i+1][j-1],f[i][j-1]); } in(m); int x,y; for(int i=1;i<=m;i++) { in(x),in(y); out(f[x][y-x+1]); putchar(\n); } return 0; }

回文密碼