CROC-MBTU 2012, Elimination Round (ACM-ICPC) H. Queries for Number of Palindromes

http://codeforces.com/contest/245/problem/H

代码及其注释:

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

#include<vector>

#include<set>

#include<map>

#include<string>

#include<queue>

#include<stack>

#include <iomanip>

using namespace std;

#define LL long long

const int INF=0x3f3f3f3f;

const int N=5002;

bool palindrome[N][N];//是否是回文

int ans[N][N];//从 l 到 r 回文的个数

char s[N];

typedef pair<int,int>palin;//回文对

queue<palin>qt;

int n;

int dp(int l,int r)

{

    if(ans[l][r]!=-1)//记忆化

    return ans[l][r];

    if(l==r)//特判

    {

        if(palindrome[l][r])

        ans[l][r]=1;

        else

        ans[l][r]=0;

        return ans[l][r];

    }

    if(l+1==r)//特判

    {

        if(palindrome[l][r])

        ans[l][r]=3;

        else

        ans[l][r]=2;

        return ans[l][r];

    }

    ans[l][r]=dp(l,r-1)+dp(l+1,r)-dp(l+1,r-1);//关键递归公式

    if(palindrome[l][r])//注意情况

    ++ans[l][r];

    return ans[l][r];

}

int main()

{

    //freopen("data.in","r",stdin);

    memset(palindrome,false,sizeof(palindrome));

    memset(ans,-1,sizeof(ans));

    gets(s);

    n=strlen(s);

    for(int i=0;i<n;++i)//初始化长度为1 和 2的回文

    {

        palindrome[i][i]=true;

        qt.push(palin(i,i));

        if(i+1<n&&s[i+1]==s[i])

        {

            palindrome[i][i+1]=true;

            qt.push(palin(i,i+1));

        }

    }

    while(!qt.empty())//用队列找出所有回文

    {

        palin x=qt.front();qt.pop();

        int l=x.first;

        int r=x.second;

        if(l-1>=0&&r+1<n&&s[l-1]==s[r+1])

        {

            palindrome[l-1][r+1]=true;

            qt.push(palin(l-1,r+1));

        }

    }

    int q;

    scanf("%d",&q);

    while(q--)

    {

        int l,r;

        scanf("%d %d",&l,&r);

        printf("%d\n",dp(l-1,r-1));

    }

    //cout<<ans[0][3]<<" "<<ans[1][3]<<" "<<ans[0][2]<<" "<<ans[1][2]<<endl;

    return 0;

}

 

 

你可能感兴趣的:(number)