Windy数

SCOI2009 Windy数

//Copyright(C)Corona.
//2018-10-07
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN=18;
long long f[MAXN][10][2];
inline long long dp(long long n)
{
    int a[MAXN],len=0;
    memset(f,0,sizeof(f));
    memset(a,0,sizeof(a));
    while(n){a[++len]=n%10;n/=10;}
    for(int i=1,j=len;i<j;i++,j--) swap(a[i],a[j]);
    
	f[0][0][1]=1;//超出最高位的只能填0,此时与上限的关系为相等 : 都是0
    
	for(int i=1;i<=len;i++)//从高位开始第 i 位数字
        for(int j=0;j<=1;j++)//枚举当前状态是从f[i-1][0] 还是f[i-1][1]转移而来
            for(int k=0;k<=9;k++)
				for(int c=0;c<=9;c++)//第i 位填 c.
           		if(j==1){
               		if(c>a[i]||abs(c-a[i])) continue;
                	else f[i][a[i]][c==a[i]] += f[i-1][a[i-1]][1];
           		}
            	else f[i][c][0] += f[i-1][j][0];
	
	long long ans=0;

	for(int i=0;i<=a[len];i++)
	{
		printf("f[%d][%d][%d]:%lld\n",len,i,i==a[i],f[len][i][i==a[i]]);
		ans += f[len][i][i==a[i]];
	}
	return ans;
}

inline int scanf()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return f*x;
}

inline void printf(int x)
{
    if(x<0){putchar('-');x=~(x-1);}
    int s[13]={0},&top=s[0];
    while(x){s[++top]=x%10;x/=10;}
    if(!top)s[++top]=0;
    while(top)putchar(s[top--]+'0');
}
int main()
{
	freopen("windy.out","w",stdout);

	int a,b;
    while(scanf("%d %d",&a,&b)==2)
	{
		printf(dp(b)-dp(a-1));
		printf("\n---\n");

	}
    return 0;
}

//unaccepted
//unfinished

posted @ 2018-10-07 20:21  昤昽  阅读(167)  评论(0编辑  收藏  举报