absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] [-31] 100324 J
[破碎的状态] [-30] Hdu 3644

[破碎的状态] [-30] 100324 A

absi2011 posted @ Jun 22, 2016 10:01:37 AM in 刷题记录 with tags DP 小高考 CF Gym 数学题 , 556 阅读

感谢@似水流年 翻译

题意:

如果某个数x修改任意一位就是回文的,那么我们称之为"几乎回文的"

求1~n中有多少个几乎回文的数

PS:回文数也是几乎回文的,因为它们可以将某一位修改为其本身

解法:

dp....数位dp....

不知道为啥cf评测机为啥要耗30ms..很有趣..

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
char a[25];
long long dp[25][2][2];
long long dp2[25][2];
long long sum=0;
long long dp_any(int flag,int x,int y=0)
{
    if (dp[x][y][flag]!=-1) return dp[x][y][flag];
    if (x==0)
    {
        dp[x][y][flag]=1;
        return 1;
    }
    long long ans=0;
    if (y==0)
    {
        if (flag)
        {
            if (x==1)
            {
                ans=9;
                dp[x][y][flag]=ans;
                return ans;
            }
            ans+=9*dp_any(0,x-2,0);
            ans+=81*dp_any(0,x-2,1);
        }
        else
        {
            if (x==1)
            {
                ans=10;
                dp[x][y][flag]=ans;
                return ans;
            }
            ans+=10*dp_any(0,x-2,0);
            ans+=90*dp_any(0,x-2,1);
        }
    }
    else
    {
        if (x==1)
        {
            ans=10;
            dp[x][y][flag]=ans;
            return ans;
        }
        ans=10*dp_any(0,x-2,1);
    }
    dp[x][y][flag]=ans;
    return ans;
}
char b[25];
int n;
bool checks()
{
    int i;
    for (i=0;i<n;i++)
    {
        if (a[i]<b[i]) return false;
        if (a[i]>b[i]) return true;
    }
    return true;
}
long long dp_not_any(int flag,int now,int visit=0)
{
    if (dp2[now][visit]!=-1) return dp2[now][visit];
    dp2[now][visit]=0;
    if ((now==0)&&(visit==0))
    {
        int i;
        for (i=0;i<(n+1)/2;i++)
        {
            b[i]=a[i];
            b[n-i-1]=a[i];
        }
        dp2[now][visit]=checks();
        return dp2[now][visit];
    }
    if ((now==0)&&(visit==1)) return 0;
    if (visit==0)
    {
        if (now==1)
        {
            if (flag)
            {
                dp2[now][visit]=a[0]-'0';
                return dp2[now][visit];
            }
            else
            {
                int i;
                for (i=0;i<(n+1)/2;i++)
                {
                    b[i]=a[i];
                    b[n-i-1]=a[i];
                }
                dp2[now][visit]=a[n/2]-'0'+checks();
                return dp2[now][visit];
            }
        }
        else
        {
            dp2[now][visit]=dp_not_any(0,now-2,0);
            dp2[now][visit]+=dp_not_any(0,now-2,1)*9;
            int i;
            for (i=0;i<(n+1)/2;i++)
            {
                b[i]=a[i];
                b[n-i-1]=a[i];
            }
            int t=n-1-(n-now)/2;
            for (i=0;i<10;i++)
            {
                b[t]='0'+i;
                if (b[t]==b[(n-now)/2]) continue;
                dp2[now][visit]+=checks();
            }
            i=(n-now)/2;
            if (flag)
            {
                dp2[now][visit]+=dp_any(0,now-2,0)*(a[i]-'1');
                dp2[now][visit]+=dp_any(0,now-2,1)*(a[i]-'1')*9;
            }
            else
            {
                dp2[now][visit]+=dp_any(0,now-2,0)*(a[i]-'0');
                dp2[now][visit]+=dp_any(0,now-2,1)*(a[i]-'0')*9;
            }
        }
    }
    else
    {
        int i=(n-now)/2;
        if (now==1)
        {
            dp2[now][visit]=a[i]-'0';
            return dp2[now][visit];
        }
        else
        {
            dp2[now][visit]=dp_any(0,now-2,1)*(a[i]-'0');
            dp2[now][visit]+=dp_not_any(0,now-2,1);
        }
    }
    return dp2[now][visit];
}
int main()
{
    freopen("almost.in","r",stdin);
    freopen("almost.out","w",stdout);
    ios::sync_with_stdio(false);
    for (;;)
    {
        scanf("%s",a);
        if (a[0]=='0') break;
        memset(dp,-1,sizeof(dp));
        memset(dp2,-1,sizeof(dp2));
        int i;
        sum=0;
        n=strlen(a);
        for (i=1;i<n;i++)
        {
            sum+=dp_any(1,i);
        }
        sum+=dp_not_any(1,n);
        cout<<sum<<'\n';
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter