Y

来源:互联网 发布:类似蝰蛇音效的软件 编辑:程序博客网 时间:2024/06/08 00:07

题目链接:https://cn.vjudge.net/contest/194559#problem/Y

大意:连续奇数的个数是偶数;连续偶数的个数是奇数的这种数的个数

分析:刚开始想着pre_ou,pre_ji这两种状态,很麻烦。后来旁敲侧击的知道了用一个judge(yes)标志一下是否满足就可以了。中间有的小地方需要注意

  这道题需要学习的地方就是状态,然后dfs的时候细心

代码如下:


#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;
int dig[20];
ll dp[20][3][3];
ll dfs(int pos,int pre,int lead,int yes,int limit)
{
    if(pos==0)
        return yes==1?1:0;
    if(lead==1&&dp[pos][pre][yes]!=-1&&!limit)
        return dp[pos][pre][yes];
    ll ans=0;
    int up=limit?dig[pos]:9;
    for(int i=0;i<=up;i++)
    {
        if(lead==0)
        {
            if(i==0)
                ans+=dfs(pos-1,0,0,1,limit&&i==up);
            else
                ans+=dfs(pos-1,i%2,1,i%2==1?0:1,limit&&i==up);//这地方一开始写错了
        }
        else//无前导0
        {
            if(i%2==1)
            {
                if(pre%2==1)
                    ans+=dfs(pos-1,1,1,yes==1?0:1,limit&&i==up);
                else//转折点,过去全是偶数,如今转折成了奇数
                {
                    if(yes==1)//前边满足条件,此前这位是奇数,个数是1个,故搜索时yes==0
                        ans+=dfs(pos-1,1,1,0,limit&&i==up);
                }
             }
            else//当前位是偶数
            {
                if(pre%2==0)
                    ans+=dfs(pos-1,0,1,yes==1?0:1,limit&&i==up);
                else//转折点
                {
                    if(yes==1)
                        ans+=dfs(pos-1,0,1,1,limit&&i==up);
                }
             }
          }
    }
    if(!limit&&lead)
        dp[pos][pre][yes]=ans;
    return ans;
}
    ll solve(ll x)
    {
        memset(dig,0,sizeof(dig));
        int id=0;
        while(x)
        {
            dig[++id]=x%10;
            x/=10;
        }
        return dfs(id,0,0,1,1);
    }






int main()
{
    memset(dp,-1,sizeof(dp));
    int T;
    ll a,b;
    int lala=1;
    cin>>T;
    while(T--)
    {
        cin>>a>>b;
        cout<<"Case "<<"#"<<lala<<":"<<" "<<solve(b)-solve(a-1)<<endl;
        lala++;
    }
    return 0;
}