码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ BALNUM Balanced Numbers(数位dp)

时间:2015-04-28 09:57:28      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:spoj balnum balanced   数位dp   

 Balanced Numbers
Time Limit:123MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu

Description

Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if:

1)      Every even digit appears an odd number of times in its decimal representation

2)      Every odd digit appears an even number of times in its decimal representation

For example, 77, 211, 6222 and 112334445555677 are balanced numbers while 351, 21, and 662 are not.

Given an interval [A, B], your task is to find the amount of balanced numbers in [A, B] where both A and B are included.

Input

The first line contains an integer T representing the number of test cases.

A test case consists of two numbers A and B separated by a single space representing the interval. You may assume that 1 <= A <= B <= 1019 

Output

For each test case, you need to write a number in a single line: the amount of balanced numbers in the corresponding interval

Example

Input:
2
1 1000
1 9
Output:
147
4

题意:求所给区间中,数位中,奇数的出现偶数次,偶数的出现技术次的个数。

题解:看了别人写的题解才知道,把数压进三进制中,0代表没有,1:奇数次

           2:偶数次

          比如:

          126099这个数:0  1  2  3  4  5  6  7  8  9(三进制中的位数)

                                1  1  1   0  0  0  1  0  0  2(表示)

            于是s=3^0*1+3^1*1+3^2*1+3^6*1+3^9*2

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#define ll long long
#define N 1010
using namespace std;

int n;

ll l,r;
int dp[22][58888];
int num[22];
int p3[20];

void init() {
    p3[0]=1;
    for(int i=1; i<=10; i++)
        p3[i]=p3[i-1]*3;
}

int new_s(int s,int d) {
    int ss=0;
    int b[12];
    memset(b,0,sizeof b);
    int l=0;
    while(s) {
        b[l++]=s%3;
        s/=3;
    }
    b[d]+=1;
    if(b[d]==3)b[d]=1;///出现3次,奇数次,变为1
    for(int i=0; i<=9; i++)
        ss+=p3[i]*b[i];
    return ss;
}

///判断是不是每一位数是否满足:奇数的都出现欧数次,偶数的都出现欧数次
bool judge(int s) {
    for(int i=0; i<=9; i++) {
        int x=s%3;
        s/=3;
        if(x==0)continue;    ///没出现
        
        ///不符合:奇数的都出现欧数次,偶数的都出现欧数次
        if(x==1&&(i&1))return 0;
        if(x==2&&!(i&1))return 0;
    }
    return 1;
}

///模板
int dfs(int i,int s,bool e,bool lze) {
    if(i==-1)return lze?0:judge(s);
    if(!e&&dp[i][s]!=-1)return dp[i][s];
    ll res=0;
    int u=e?num[i]:9;
    for(int d=0; d<=u; d++) {
        if(lze) {///是前导0
            if(d==0)res+=dfs(i-1,s,e&&d==u,lze);
            else   res+=dfs(i-1,new_s(s,d),e&&d==u,lze&&d==0);
        } else
            res+=dfs(i-1,new_s(s,d),e&&d==u,lze&&d==0);
    }
    return (e)?res:dp[i][s]=res;
}

int solve(ll x) {
    int len=0;
    while(x) {
        num[len++]=x%10;
        x/=10;
    }
    return dfs(len-1,0,1,1);
}

int main() {
    //freopen("in.txt","r",stdin);
    cin>>n;
    init();
    memset(dp,-1,sizeof dp);
    while(n--) {
        scanf("%lld%lld",&l,&r);
        printf("%d\n",solve(r)-solve(l-1));
    }
    return 0;
}


SPOJ BALNUM Balanced Numbers(数位dp)

标签:spoj balnum balanced   数位dp   

原文地址:http://blog.csdn.net/acm_baihuzi/article/details/45315673

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!